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 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 case SkXfermode::kZero_Coeff: /** 0 */ | 151 case SkXfermode::kZero_Coeff: /** 0 */ |
152 *str = ""; | 152 *str = ""; |
153 break; | 153 break; |
154 case SkXfermode::kOne_Coeff: /** 1 */ | 154 case SkXfermode::kOne_Coeff: /** 1 */ |
155 *str = value; | 155 *str = value; |
156 break; | 156 break; |
157 case SkXfermode::kSC_Coeff: | 157 case SkXfermode::kSC_Coeff: |
158 str->printf("(%s * %s)", src, value); | 158 str->printf("(%s * %s)", src, value); |
159 break; | 159 break; |
160 case SkXfermode::kISC_Coeff: | 160 case SkXfermode::kISC_Coeff: |
161 str->printf("((%s - %s) * %s)", GrGLSLOnesVecf(4), src, value); | 161 str->printf("((vec4(1) - %s) * %s)", src, value); |
162 break; | 162 break; |
163 case SkXfermode::kDC_Coeff: | 163 case SkXfermode::kDC_Coeff: |
164 str->printf("(%s * %s)", dst, value); | 164 str->printf("(%s * %s)", dst, value); |
165 break; | 165 break; |
166 case SkXfermode::kIDC_Coeff: | 166 case SkXfermode::kIDC_Coeff: |
167 str->printf("((%s - %s) * %s)", GrGLSLOnesVecf(4), dst, value); | 167 str->printf("((vec4(1) - %s) * %s)", dst, value); |
168 break; | 168 break; |
169 case SkXfermode::kSA_Coeff: /** src alpha */ | 169 case SkXfermode::kSA_Coeff: /** src alpha */ |
170 str->printf("(%s.a * %s)", src, value); | 170 str->printf("(%s.a * %s)", src, value); |
171 break; | 171 break; |
172 case SkXfermode::kISA_Coeff: /** inverse src alpha (i.e. 1 - sa) */ | 172 case SkXfermode::kISA_Coeff: /** inverse src alpha (i.e. 1 - sa) */ |
173 str->printf("((1.0 - %s.a) * %s)", src, value); | 173 str->printf("((1.0 - %s.a) * %s)", src, value); |
174 break; | 174 break; |
175 case SkXfermode::kDA_Coeff: /** dst alpha */ | 175 case SkXfermode::kDA_Coeff: /** dst alpha */ |
176 str->printf("(%s.a * %s)", dst, value); | 176 str->printf("(%s.a * %s)", dst, value); |
177 break; | 177 break; |
(...skipping 11 matching lines...) Expand all Loading... |
189 */ | 189 */ |
190 void add_color_filter(GrGLShaderBuilder* builder, | 190 void add_color_filter(GrGLShaderBuilder* builder, |
191 const char * outputVar, | 191 const char * outputVar, |
192 SkXfermode::Coeff uniformCoeff, | 192 SkXfermode::Coeff uniformCoeff, |
193 SkXfermode::Coeff colorCoeff, | 193 SkXfermode::Coeff colorCoeff, |
194 const char* filterColor, | 194 const char* filterColor, |
195 const char* inColor) { | 195 const char* inColor) { |
196 SkString colorStr, constStr; | 196 SkString colorStr, constStr; |
197 blend_term_string(&colorStr, colorCoeff, filterColor, inColor, inColor); | 197 blend_term_string(&colorStr, colorCoeff, filterColor, inColor, inColor); |
198 blend_term_string(&constStr, uniformCoeff, filterColor, inColor, filterColor
); | 198 blend_term_string(&constStr, uniformCoeff, filterColor, inColor, filterColor
); |
199 | 199 GrGLSLExpr<4> sum; |
200 SkString sum; | 200 if (colorStr.isEmpty() && constStr.isEmpty()) { |
201 GrGLSLAddf<4>(&sum, colorStr.c_str(), constStr.c_str()); | 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 } |
202 builder->fsCodeAppendf("\t%s = %s;\n", outputVar, sum.c_str()); | 209 builder->fsCodeAppendf("\t%s = %s;\n", outputVar, sum.c_str()); |
203 } | 210 } |
204 } | 211 } |
205 | 212 |
206 namespace { | |
207 | |
208 void expand_known_value4f(SkString* string, GrSLConstantVec vec) { | |
209 SkASSERT(string->isEmpty() == (vec != kNone_GrSLConstantVec)); | |
210 switch (vec) { | |
211 case kNone_GrSLConstantVec: | |
212 break; | |
213 case kZeros_GrSLConstantVec: | |
214 *string = GrGLSLZerosVecf(4); | |
215 break; | |
216 case kOnes_GrSLConstantVec: | |
217 *string = GrGLSLOnesVecf(4); | |
218 break; | |
219 } | |
220 } | |
221 | |
222 } | |
223 | |
224 bool GrGLProgram::genProgram(GrGLShaderBuilder* builder, | 213 bool GrGLProgram::genProgram(GrGLShaderBuilder* builder, |
225 const GrEffectStage* colorStages[], | 214 const GrEffectStage* colorStages[], |
226 const GrEffectStage* coverageStages[]) { | 215 const GrEffectStage* coverageStages[]) { |
227 SkASSERT(0 == fProgramID); | 216 SkASSERT(0 == fProgramID); |
228 | 217 |
229 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); | 218 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); |
230 | 219 |
231 // incoming color to current stage being processed. | 220 // incoming color to current stage being processed. |
232 SkString inColor = builder->getInputColor(); | 221 GrGLSLExpr<4> inColor = builder->getInputColor(); |
233 GrSLConstantVec knownColorValue = builder->getKnownColorValue(); | |
234 | 222 |
235 // Get the coeffs for the Mode-based color filter, determine if color is nee
ded. | 223 // Get the coeffs for the Mode-based color filter, determine if color is nee
ded. |
236 SkXfermode::Coeff colorCoeff; | 224 SkXfermode::Coeff colorCoeff; |
237 SkXfermode::Coeff filterColorCoeff; | 225 SkXfermode::Coeff filterColorCoeff; |
238 SkAssertResult( | 226 SkAssertResult( |
239 SkXfermode::ModeAsCoeff(header.fColorFilterXfermode, | 227 SkXfermode::ModeAsCoeff(header.fColorFilterXfermode, |
240 &filterColorCoeff, | 228 &filterColorCoeff, |
241 &colorCoeff)); | 229 &colorCoeff)); |
242 bool needColor, needFilterColor; | 230 bool needColor, needFilterColor; |
243 need_blend_inputs(filterColorCoeff, colorCoeff, &needFilterColor, &needColor
); | 231 need_blend_inputs(filterColorCoeff, colorCoeff, &needFilterColor, &needColor
); |
244 | 232 |
245 fColorEffects.reset( | 233 fColorEffects.reset( |
246 builder->createAndEmitEffects(colorStages, | 234 builder->createAndEmitEffects(colorStages, |
247 fDesc.effectKeys(), | 235 fDesc.effectKeys(), |
248 needColor ? fDesc.numColorEffects() : 0, | 236 needColor ? fDesc.numColorEffects() : 0, |
249 &inColor, | 237 &inColor)); |
250 &knownColorValue)); | |
251 | 238 |
252 // Insert the color filter. This will soon be replaced by a color effect. | 239 // Insert the color filter. This will soon be replaced by a color effect. |
253 if (SkXfermode::kDst_Mode != header.fColorFilterXfermode) { | 240 if (SkXfermode::kDst_Mode != header.fColorFilterXfermode) { |
254 const char* colorFilterColorUniName = NULL; | 241 const char* colorFilterColorUniName = NULL; |
255 fUniformHandles.fColorFilterUni = builder->addUniform(GrGLShaderBuilder:
:kFragment_Visibility, | 242 fUniformHandles.fColorFilterUni = builder->addUniform(GrGLShaderBuilder:
:kFragment_Visibility, |
256 kVec4f_GrSLType, "
FilterColor", | 243 kVec4f_GrSLType, "
FilterColor", |
257 &colorFilterColorU
niName); | 244 &colorFilterColorU
niName); |
258 | 245 |
259 builder->fsCodeAppend("\tvec4 filteredColor;\n"); | 246 builder->fsCodeAppend("\tvec4 filteredColor;\n"); |
260 const char* color; | |
261 // add_color_filter requires a real input string. | |
262 if (knownColorValue == kOnes_GrSLConstantVec) { | |
263 color = GrGLSLOnesVecf(4); | |
264 } else if (knownColorValue == kZeros_GrSLConstantVec) { | |
265 color = GrGLSLZerosVecf(4); | |
266 } else { | |
267 color = inColor.c_str(); | |
268 } | |
269 add_color_filter(builder, "filteredColor", filterColorCoeff, | 247 add_color_filter(builder, "filteredColor", filterColorCoeff, |
270 colorCoeff, colorFilterColorUniName, color); | 248 colorCoeff, colorFilterColorUniName, inColor.c_str()); |
271 inColor = "filteredColor"; | 249 inColor = "filteredColor"; |
272 } | 250 } |
273 | 251 |
274 /////////////////////////////////////////////////////////////////////////// | 252 /////////////////////////////////////////////////////////////////////////// |
275 // compute the partial coverage | 253 // compute the partial coverage |
276 SkString inCoverage = builder->getInputCoverage(); | 254 GrGLSLExpr<4> inCoverage = builder->getInputCoverage(); |
277 GrSLConstantVec knownCoverageValue = builder->getKnownCoverageValue(); | |
278 | 255 |
279 fCoverageEffects.reset( | 256 fCoverageEffects.reset( |
280 builder->createAndEmitEffects(coverageStages, | 257 builder->createAndEmitEffects(coverageStages, |
281 fDesc.getEffectKeys() + fDesc.numColorEffe
cts(), | 258 fDesc.getEffectKeys() + fDesc.numColorEffe
cts(), |
282 fDesc.numCoverageEffects(), | 259 fDesc.numCoverageEffects(), |
283 &inCoverage, | 260 &inCoverage)); |
284 &knownCoverageValue)); | |
285 | 261 |
286 // discard if coverage is zero | 262 // discard if coverage is zero |
287 if (header.fDiscardIfZeroCoverage && kOnes_GrSLConstantVec != knownCoverageV
alue) { | 263 if (header.fDiscardIfZeroCoverage && !inCoverage.isOnes()) { |
288 if (kZeros_GrSLConstantVec == knownCoverageValue) { | 264 if (inCoverage.isZeros()) { |
289 // This is unfortunate. | 265 // This is unfortunate. |
290 builder->fsCodeAppend("\tdiscard;\n"); | 266 builder->fsCodeAppend("\tdiscard;\n"); |
291 } else { | 267 } else { |
292 builder->fsCodeAppendf("\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n
\t\tdiscard;\n\t}\n", | 268 builder->fsCodeAppendf("\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n
\t\tdiscard;\n\t}\n", |
293 inCoverage.c_str()); | 269 inCoverage.c_str()); |
294 } | 270 } |
295 } | 271 } |
296 | 272 |
297 if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(header.fCoverageOutpu
t)) { | 273 if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(header.fCoverageOutpu
t)) { |
298 const char* secondaryOutputName = builder->enableSecondaryOutput(); | 274 const char* secondaryOutputName = builder->enableSecondaryOutput(); |
299 | 275 |
300 // default coeff to ones for kCoverage_DualSrcOutput | 276 // default coeff to ones for kCoverage_DualSrcOutput |
301 SkString coeff; | 277 GrGLSLExpr<4> coeff(1); |
302 GrSLConstantVec knownCoeffValue = kOnes_GrSLConstantVec; | |
303 if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCov
erageOutput) { | 278 if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCov
erageOutput) { |
304 // Get (1-A) into coeff | 279 // Get (1-A) into coeff |
305 SkString inColorAlpha; | 280 coeff = GrGLSLExprCast4(1 - GrGLSLExprExtractAlpha(inColor)); |
306 GrGLSLGetComponent4f(&inColorAlpha, | |
307 inColor.c_str(), | |
308 kA_GrColorComponentFlag, | |
309 knownColorValue, | |
310 true); | |
311 knownCoeffValue = GrGLSLSubtractf<1>(&coeff, | |
312 NULL, | |
313 inColorAlpha.c_str(), | |
314 kOnes_GrSLConstantVec, | |
315 knownColorValue, | |
316 true); | |
317 } else if (GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput == head
er.fCoverageOutput) { | 281 } else if (GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput == head
er.fCoverageOutput) { |
318 // Get (1-RGBA) into coeff | 282 // Get (1-RGBA) into coeff |
319 knownCoeffValue = GrGLSLSubtractf<4>(&coeff, | 283 coeff = 1 - inColor; |
320 NULL, | |
321 inColor.c_str(), | |
322 kOnes_GrSLConstantVec, | |
323 knownColorValue, | |
324 true); | |
325 } | 284 } |
326 // Get coeff * coverage into modulate and then write that to the dual so
urce output. | 285 // Get coeff * coverage into modulate and then write that to the dual so
urce output. |
327 SkString modulate; | 286 builder->fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, (coeff * inC
overage).c_str()); |
328 GrGLSLModulatef<4>(&modulate, | |
329 coeff.c_str(), | |
330 inCoverage.c_str(), | |
331 knownCoeffValue, | |
332 knownCoverageValue, | |
333 false); | |
334 builder->fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, modulate.c_s
tr()); | |
335 } | 287 } |
336 | 288 |
337 /////////////////////////////////////////////////////////////////////////// | 289 /////////////////////////////////////////////////////////////////////////// |
338 // combine color and coverage as frag color | 290 // combine color and coverage as frag color |
339 | 291 |
340 // Get "color * coverage" into fragColor | 292 // Get "color * coverage" into fragColor |
341 SkString fragColor; | 293 GrGLSLExpr<4> fragColor = inColor * inCoverage; |
342 GrSLConstantVec knownFragColorValue = GrGLSLModulatef<4>(&fragColor, | |
343 inColor.c_str(), | |
344 inCoverage.c_str(), | |
345 knownColorValue, | |
346 knownCoverageValue, | |
347 true); | |
348 // Now tack on "+(1-coverage)dst onto the frag color if we were asked to do
so. | 294 // Now tack on "+(1-coverage)dst onto the frag color if we were asked to do
so. |
349 if (GrGLProgramDesc::kCombineWithDst_CoverageOutput == header.fCoverageOutpu
t) { | 295 if (GrGLProgramDesc::kCombineWithDst_CoverageOutput == header.fCoverageOutpu
t) { |
350 SkString dstCoeff; | 296 GrGLSLExpr<4> dstCoeff = 1 - inCoverage; |
351 GrSLConstantVec knownDstCoeffValue = GrGLSLSubtractf<4>(&dstCoeff, | 297 |
352 NULL, | 298 GrGLSLExpr<4> dstContribution = dstCoeff * GrGLSLExpr<4>(builder->dstCol
or()); |
353 inCoverage.c_str
(), | 299 |
354 kOnes_GrSLConsta
ntVec, | 300 fragColor = fragColor + dstContribution; |
355 knownCoverageVal
ue, | |
356 true); | |
357 SkString dstContribution; | |
358 GrSLConstantVec knownDstContributionValue = GrGLSLModulatef<4>(&dstContr
ibution, | |
359 dstCoeff.
c_str(), | |
360 builder->
dstColor(), | |
361 knownDstC
oeffValue, | |
362 kNone_GrS
LConstantVec, | |
363 true); | |
364 SkString oldFragColor = fragColor; | |
365 fragColor.reset(); | |
366 GrGLSLAddf<4>(&fragColor, | |
367 oldFragColor.c_str(), | |
368 dstContribution.c_str(), | |
369 knownFragColorValue, | |
370 knownDstContributionValue, | |
371 false); | |
372 } else { | |
373 expand_known_value4f(&fragColor, knownFragColorValue); | |
374 } | 301 } |
375 builder->fsCodeAppendf("\t%s = %s;\n", builder->getColorOutputName(), fragCo
lor.c_str()); | 302 builder->fsCodeAppendf("\t%s = %s;\n", builder->getColorOutputName(), fragCo
lor.c_str()); |
376 | 303 |
377 if (!builder->finish(&fProgramID)) { | 304 if (!builder->finish(&fProgramID)) { |
378 return false; | 305 return false; |
379 } | 306 } |
380 | 307 |
381 fUniformHandles.fRTHeightUni = builder->getRTHeightUniform(); | 308 fUniformHandles.fRTHeightUni = builder->getRTHeightUniform(); |
382 fUniformHandles.fDstCopyTopLeftUni = builder->getDstCopyTopLeftUniform(); | 309 fUniformHandles.fDstCopyTopLeftUni = builder->getDstCopyTopLeftUniform(); |
383 fUniformHandles.fDstCopyScaleUni = builder->getDstCopyScaleUniform(); | 310 fUniformHandles.fDstCopyScaleUni = builder->getDstCopyScaleUniform(); |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
565 | 492 |
566 fMatrixState.fViewMatrix = drawState.getViewMatrix(); | 493 fMatrixState.fViewMatrix = drawState.getViewMatrix(); |
567 fMatrixState.fRenderTargetSize = size; | 494 fMatrixState.fRenderTargetSize = size; |
568 fMatrixState.fRenderTargetOrigin = rt->origin(); | 495 fMatrixState.fRenderTargetOrigin = rt->origin(); |
569 | 496 |
570 GrGLfloat viewMatrix[3 * 3]; | 497 GrGLfloat viewMatrix[3 * 3]; |
571 fMatrixState.getGLMatrix<3>(viewMatrix); | 498 fMatrixState.getGLMatrix<3>(viewMatrix); |
572 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, viewMatrix); | 499 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, viewMatrix); |
573 } | 500 } |
574 } | 501 } |
OLD | NEW |