Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(167)

Side by Side Diff: src/gpu/gl/GrGLProgram.cpp

Issue 25023003: Implement color filter as GrGLEffect (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Fix a small thinko Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 27 matching lines...) Expand all
38 const GrEffectStage* colorStages[], 38 const GrEffectStage* colorStages[],
39 const GrEffectStage* coverageStages[]) 39 const GrEffectStage* coverageStages[])
40 : fGpu(gpu) 40 : fGpu(gpu)
41 , fUniformManager(gpu) { 41 , fUniformManager(gpu) {
42 fDesc = desc; 42 fDesc = desc;
43 fProgramID = 0; 43 fProgramID = 0;
44 44
45 fDstCopyTexUnit = -1; 45 fDstCopyTexUnit = -1;
46 46
47 fColor = GrColor_ILLEGAL; 47 fColor = GrColor_ILLEGAL;
48 fColorFilterColor = GrColor_ILLEGAL;
49 48
50 fColorEffects.reset(desc.numColorEffects()); 49 fColorEffects.reset(desc.numColorEffects());
51 fCoverageEffects.reset(desc.numCoverageEffects()); 50 fCoverageEffects.reset(desc.numCoverageEffects());
52 51
53 this->genProgram(colorStages, coverageStages); 52 this->genProgram(colorStages, coverageStages);
54 } 53 }
55 54
56 GrGLProgram::~GrGLProgram() { 55 GrGLProgram::~GrGLProgram() {
57 if (fProgramID) { 56 if (fProgramID) {
58 GL_CALL(DeleteProgram(fProgramID)); 57 GL_CALL(DeleteProgram(fProgramID));
(...skipping 19 matching lines...) Expand all
78 case GrGLProgramDesc::kCombineWithDst_CoverageOutput: 77 case GrGLProgramDesc::kCombineWithDst_CoverageOutput:
79 // We should only have set this if the blend was specified as (1, 0) 78 // We should only have set this if the blend was specified as (1, 0)
80 SkASSERT(kOne_GrBlendCoeff == *srcCoeff && kZero_GrBlendCoeff == *ds tCoeff); 79 SkASSERT(kOne_GrBlendCoeff == *srcCoeff && kZero_GrBlendCoeff == *ds tCoeff);
81 break; 80 break;
82 default: 81 default:
83 GrCrash("Unexpected coverage output"); 82 GrCrash("Unexpected coverage output");
84 break; 83 break;
85 } 84 }
86 } 85 }
87 86
88 namespace {
89 // given two blend coefficients determine whether the src
90 // and/or dst computation can be omitted.
91 inline void need_blend_inputs(SkXfermode::Coeff srcCoeff,
92 SkXfermode::Coeff dstCoeff,
93 bool* needSrcValue,
94 bool* needDstValue) {
95 if (SkXfermode::kZero_Coeff == srcCoeff) {
96 switch (dstCoeff) {
97 // these all read the src
98 case SkXfermode::kSC_Coeff:
99 case SkXfermode::kISC_Coeff:
100 case SkXfermode::kSA_Coeff:
101 case SkXfermode::kISA_Coeff:
102 *needSrcValue = true;
103 break;
104 default:
105 *needSrcValue = false;
106 break;
107 }
108 } else {
109 *needSrcValue = true;
110 }
111 if (SkXfermode::kZero_Coeff == dstCoeff) {
112 switch (srcCoeff) {
113 // these all read the dst
114 case SkXfermode::kDC_Coeff:
115 case SkXfermode::kIDC_Coeff:
116 case SkXfermode::kDA_Coeff:
117 case SkXfermode::kIDA_Coeff:
118 *needDstValue = true;
119 break;
120 default:
121 *needDstValue = false;
122 break;
123 }
124 } else {
125 *needDstValue = true;
126 }
127 }
128
129 /**
130 * Create a blend_coeff * value string to be used in shader code. Sets empty
131 * string if result is trivially zero.
132 */
133 inline void blend_term_string(SkString* str, SkXfermode::Coeff coeff,
134 const char* src, const char* dst,
135 const char* value) {
136 switch (coeff) {
137 case SkXfermode::kZero_Coeff: /** 0 */
138 *str = "";
139 break;
140 case SkXfermode::kOne_Coeff: /** 1 */
141 *str = value;
142 break;
143 case SkXfermode::kSC_Coeff:
144 str->printf("(%s * %s)", src, value);
145 break;
146 case SkXfermode::kISC_Coeff:
147 str->printf("((%s - %s) * %s)", GrGLSLExpr<4>(1).c_str(), src, value);
148 break;
149 case SkXfermode::kDC_Coeff:
150 str->printf("(%s * %s)", dst, value);
151 break;
152 case SkXfermode::kIDC_Coeff:
153 str->printf("((%s - %s) * %s)", GrGLSLExpr<4>(1).c_str(), dst, value);
154 break;
155 case SkXfermode::kSA_Coeff: /** src alpha */
156 str->printf("(%s.a * %s)", src, value);
157 break;
158 case SkXfermode::kISA_Coeff: /** inverse src alpha (i.e. 1 - sa) */
159 str->printf("((1.0 - %s.a) * %s)", src, value);
160 break;
161 case SkXfermode::kDA_Coeff: /** dst alpha */
162 str->printf("(%s.a * %s)", dst, value);
163 break;
164 case SkXfermode::kIDA_Coeff: /** inverse dst alpha (i.e. 1 - da) */
165 str->printf("((1.0 - %s.a) * %s)", dst, value);
166 break;
167 default:
168 GrCrash("Unexpected xfer coeff.");
169 break;
170 }
171 }
172 /**
173 * Adds a line to the fragment shader code which modifies the color by
174 * the specified color filter.
175 */
176 void add_color_filter(GrGLShaderBuilder* builder,
177 const char * outputVar,
178 SkXfermode::Coeff uniformCoeff,
179 SkXfermode::Coeff colorCoeff,
180 const char* filterColor,
181 const char* inColor) {
182 SkString colorStr, constStr;
183 blend_term_string(&colorStr, colorCoeff, filterColor, inColor, inColor);
184 blend_term_string(&constStr, uniformCoeff, filterColor, inColor, filterColor );
185 GrGLSLExpr<4> sum;
186 if (colorStr.isEmpty() && constStr.isEmpty()) {
187 sum = GrGLSLExpr<4>(0);
188 } else if (colorStr.isEmpty()) {
189 sum = constStr;
190 } else if (constStr.isEmpty()) {
191 sum = colorStr;
192 } else {
193 sum = GrGLSLExpr<4>(colorStr) + GrGLSLExpr<4>(constStr);
194 }
195 builder->fsCodeAppendf("\t%s = %s;\n", outputVar, sum.c_str());
196 }
197 }
198
199 bool GrGLProgram::genProgram(const GrEffectStage* colorStages[], 87 bool GrGLProgram::genProgram(const GrEffectStage* colorStages[],
200 const GrEffectStage* coverageStages[]) { 88 const GrEffectStage* coverageStages[]) {
201 SkASSERT(0 == fProgramID); 89 SkASSERT(0 == fProgramID);
202 90
203 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); 91 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
204 92
205 bool needsVertexShader = true; 93 bool needsVertexShader = true;
206 94
207 GrGLShaderBuilder builder(fGpu, fUniformManager, fDesc, needsVertexShader); 95 GrGLShaderBuilder builder(fGpu, fUniformManager, fDesc, needsVertexShader);
208 if (GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder.getVertexBuild er()) { 96 if (GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder.getVertexBuild er()) {
209 fUniformHandles.fViewMatrixUni = vertexBuilder->getViewMatrixUniform(); 97 fUniformHandles.fViewMatrixUni = vertexBuilder->getViewMatrixUniform();
210 } 98 }
211 99
212 // incoming color to current stage being processed. 100 // incoming color to current stage being processed.
213 GrGLSLExpr<4> inColor = builder.getInputColor(); 101 GrGLSLExpr<4> inColor = builder.getInputColor();
214 102
215 // Get the coeffs for the Mode-based color filter, determine if color is nee ded.
216 SkXfermode::Coeff colorCoeff;
217 SkXfermode::Coeff filterColorCoeff;
218 SkAssertResult(
219 SkXfermode::ModeAsCoeff(static_cast<SkXfermode::Mode>(header.fColorFilte rXfermode),
220 &filterColorCoeff,
221 &colorCoeff));
222 bool needColor, needFilterColor;
223 need_blend_inputs(filterColorCoeff, colorCoeff, &needFilterColor, &needColor );
224
225 // used in order for builder to return the per-stage uniform handles. 103 // used in order for builder to return the per-stage uniform handles.
226 typedef SkTArray<GrGLUniformManager::UniformHandle, true>* UniHandleArrayPtr ; 104 typedef SkTArray<GrGLUniformManager::UniformHandle, true>* UniHandleArrayPtr ;
227 int maxColorOrCovEffectCnt = GrMax(fDesc.numColorEffects(), fDesc.numCoverag eEffects()); 105 int maxColorOrCovEffectCnt = GrMax(fDesc.numColorEffects(), fDesc.numCoverag eEffects());
228 SkAutoTArray<UniHandleArrayPtr> effectUniformArrays(maxColorOrCovEffectCnt); 106 SkAutoTArray<UniHandleArrayPtr> effectUniformArrays(maxColorOrCovEffectCnt);
229 SkAutoTArray<GrGLEffect*> glEffects(maxColorOrCovEffectCnt); 107 SkAutoTArray<GrGLEffect*> glEffects(maxColorOrCovEffectCnt);
230 108
231 if (needColor) { 109 if (fDesc.numColorEffects()) {
232 for (int e = 0; e < fDesc.numColorEffects(); ++e) { 110 for (int e = 0; e < fDesc.numColorEffects(); ++e) {
233 effectUniformArrays[e] = &fColorEffects[e].fSamplerUnis; 111 effectUniformArrays[e] = &fColorEffects[e].fSamplerUnis;
234 } 112 }
235 113
236 builder.emitEffects(colorStages, 114 builder.emitEffects(colorStages,
237 fDesc.effectKeys(), 115 fDesc.effectKeys(),
238 fDesc.numColorEffects(), 116 fDesc.numColorEffects(),
239 &inColor, 117 &inColor,
240 effectUniformArrays.get(), 118 effectUniformArrays.get(),
241 glEffects.get()); 119 glEffects.get());
242 120
243 for (int e = 0; e < fDesc.numColorEffects(); ++e) { 121 for (int e = 0; e < fDesc.numColorEffects(); ++e) {
244 fColorEffects[e].fGLEffect = glEffects[e]; 122 fColorEffects[e].fGLEffect = glEffects[e];
245 } 123 }
246 } 124 }
247 125
248 // Insert the color filter. This will soon be replaced by a color effect.
249 if (SkXfermode::kDst_Mode != header.fColorFilterXfermode) {
250 const char* colorFilterColorUniName = NULL;
251 fUniformHandles.fColorFilterUni = builder.addUniform(GrGLShaderBuilder:: kFragment_Visibility,
252 kVec4f_GrSLType, "F ilterColor",
253 &colorFilterColorUn iName);
254
255 builder.fsCodeAppend("\tvec4 filteredColor;\n");
256 add_color_filter(&builder, "filteredColor", filterColorCoeff,
257 colorCoeff, colorFilterColorUniName, inColor.c_str());
258 inColor = "filteredColor";
259 }
260
261 /////////////////////////////////////////////////////////////////////////// 126 ///////////////////////////////////////////////////////////////////////////
262 // compute the partial coverage 127 // compute the partial coverage
263 GrGLSLExpr<4> inCoverage = builder.getInputCoverage(); 128 GrGLSLExpr<4> inCoverage = builder.getInputCoverage();
264 129
265 for (int e = 0; e < fDesc.numCoverageEffects(); ++e) { 130 for (int e = 0; e < fDesc.numCoverageEffects(); ++e) {
266 effectUniformArrays[e] = &fCoverageEffects[e].fSamplerUnis; 131 effectUniformArrays[e] = &fCoverageEffects[e].fSamplerUnis;
267 } 132 }
268 133
269 builder.emitEffects(coverageStages, 134 builder.emitEffects(coverageStages,
270 fDesc.getEffectKeys() + fDesc.numColorEffects(), 135 fDesc.getEffectKeys() + fDesc.numColorEffects(),
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 coverage = drawState.getCoverage(); 271 coverage = drawState.getCoverage();
407 } else { 272 } else {
408 color = drawState.getColor(); 273 color = drawState.getColor();
409 coverage = drawState.getCoverage(); 274 coverage = drawState.getCoverage();
410 } 275 }
411 276
412 this->setColor(drawState, color, sharedState); 277 this->setColor(drawState, color, sharedState);
413 this->setCoverage(drawState, coverage, sharedState); 278 this->setCoverage(drawState, coverage, sharedState);
414 this->setMatrixAndRenderTargetHeight(drawState); 279 this->setMatrixAndRenderTargetHeight(drawState);
415 280
416 // Setup the SkXfermode::Mode-based colorfilter uniform if necessary
417 if (fUniformHandles.fColorFilterUni.isValid() &&
418 fColorFilterColor != drawState.getColorFilterColor()) {
419 GrGLfloat c[4];
420 GrColorToRGBAFloat(drawState.getColorFilterColor(), c);
421 fUniformManager.set4fv(fUniformHandles.fColorFilterUni, 0, 1, c);
422 fColorFilterColor = drawState.getColorFilterColor();
423 }
424
425 if (NULL != dstCopy) { 281 if (NULL != dstCopy) {
426 if (fUniformHandles.fDstCopyTopLeftUni.isValid()) { 282 if (fUniformHandles.fDstCopyTopLeftUni.isValid()) {
427 fUniformManager.set2f(fUniformHandles.fDstCopyTopLeftUni, 283 fUniformManager.set2f(fUniformHandles.fDstCopyTopLeftUni,
428 static_cast<GrGLfloat>(dstCopy->offset().fX), 284 static_cast<GrGLfloat>(dstCopy->offset().fX),
429 static_cast<GrGLfloat>(dstCopy->offset().fY)); 285 static_cast<GrGLfloat>(dstCopy->offset().fY));
430 fUniformManager.set2f(fUniformHandles.fDstCopyScaleUni, 286 fUniformManager.set2f(fUniformHandles.fDstCopyScaleUni,
431 1.f / dstCopy->texture()->width(), 287 1.f / dstCopy->texture()->width(),
432 1.f / dstCopy->texture()->height()); 288 1.f / dstCopy->texture()->height());
433 GrGLTexture* texture = static_cast<GrGLTexture*>(dstCopy->texture()) ; 289 GrGLTexture* texture = static_cast<GrGLTexture*>(dstCopy->texture()) ;
434 static GrTextureParams kParams; // the default is clamp, nearest fil tering. 290 static GrTextureParams kParams; // the default is clamp, nearest fil tering.
435 fGpu->bindTexture(fDstCopyTexUnit, kParams, texture); 291 fGpu->bindTexture(fDstCopyTexUnit, kParams, texture);
436 } else { 292 } else {
437 SkASSERT(!fUniformHandles.fDstCopyScaleUni.isValid()); 293 SkASSERT(!fUniformHandles.fDstCopyScaleUni.isValid());
438 SkASSERT(!fUniformHandles.fDstCopySamplerUni.isValid()); 294 SkASSERT(!fUniformHandles.fDstCopySamplerUni.isValid());
439 } 295 }
440 } else { 296 } else {
441 SkASSERT(!fUniformHandles.fDstCopyTopLeftUni.isValid()); 297 SkASSERT(!fUniformHandles.fDstCopyTopLeftUni.isValid());
442 SkASSERT(!fUniformHandles.fDstCopyScaleUni.isValid()); 298 SkASSERT(!fUniformHandles.fDstCopyScaleUni.isValid());
443 SkASSERT(!fUniformHandles.fDstCopySamplerUni.isValid()); 299 SkASSERT(!fUniformHandles.fDstCopySamplerUni.isValid());
444 } 300 }
445 301
446 for (int e = 0; e < fColorEffects.count(); ++e) { 302 for (int e = 0; e < fColorEffects.count(); ++e) {
447 // We may have omitted the GrGLEffect because of the color filter logic in genProgram. 303 SkASSERT(NULL != fColorEffects[e].fGLEffect);
448 // This can be removed when the color filter is an effect. 304 this->setEffectData(*colorStages[e], fColorEffects[e]);
449 if (NULL != fColorEffects[e].fGLEffect) {
450 this->setEffectData(*colorStages[e], fColorEffects[e]);
451 }
452 } 305 }
453 306
454 for (int e = 0; e < fCoverageEffects.count(); ++e) { 307 for (int e = 0; e < fCoverageEffects.count(); ++e) {
455 if (NULL != fCoverageEffects[e].fGLEffect) { 308 SkASSERT(NULL != fCoverageEffects[e].fGLEffect);
456 this->setEffectData(*coverageStages[e], fCoverageEffects[e]); 309 this->setEffectData(*coverageStages[e], fCoverageEffects[e]);
457 }
458 } 310 }
459 } 311 }
460 312
461 void GrGLProgram::setColor(const GrDrawState& drawState, 313 void GrGLProgram::setColor(const GrDrawState& drawState,
462 GrColor color, 314 GrColor color,
463 SharedGLState* sharedState) { 315 SharedGLState* sharedState) {
464 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); 316 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
465 if (!drawState.hasColorVertexAttribute()) { 317 if (!drawState.hasColorVertexAttribute()) {
466 switch (header.fColorInput) { 318 switch (header.fColorInput) {
467 case GrGLProgramDesc::kAttribute_ColorInput: 319 case GrGLProgramDesc::kAttribute_ColorInput:
468 SkASSERT(-1 != header.fColorAttributeIndex); 320 SkASSERT(-1 != header.fColorAttributeIndex);
469 if (sharedState->fConstAttribColor != color || 321 if (sharedState->fConstAttribColor != color ||
470 sharedState->fConstAttribColorIndex != header.fColorAttribut eIndex) { 322 sharedState->fConstAttribColorIndex != header.fColorAttribut eIndex) {
471 // OpenGL ES only supports the float varieties of glVertexAt trib 323 // OpenGL ES only supports the float varieties of glVertexAt trib
472 GrGLfloat c[4]; 324 GrGLfloat c[4];
473 GrColorToRGBAFloat(color, c); 325 GrColorToRGBAFloat(color, c);
474 GL_CALL(VertexAttrib4fv(header.fColorAttributeIndex, c)); 326 GL_CALL(VertexAttrib4fv(header.fColorAttributeIndex, c));
475 sharedState->fConstAttribColor = color; 327 sharedState->fConstAttribColor = color;
476 sharedState->fConstAttribColorIndex = header.fColorAttribute Index; 328 sharedState->fConstAttribColorIndex = header.fColorAttribute Index;
477 } 329 }
478 break; 330 break;
479 case GrGLProgramDesc::kUniform_ColorInput: 331 case GrGLProgramDesc::kUniform_ColorInput:
480 if (fColor != color) { 332 if (fColor != color && fUniformHandles.fColorUni.isValid()) {
481 // OpenGL ES doesn't support unsigned byte varieties of glUn iform 333 // OpenGL ES doesn't support unsigned byte varieties of glUn iform
482 GrGLfloat c[4]; 334 GrGLfloat c[4];
483 GrColorToRGBAFloat(color, c); 335 GrColorToRGBAFloat(color, c);
484 fUniformManager.set4fv(fUniformHandles.fColorUni, 0, 1, c); 336 fUniformManager.set4fv(fUniformHandles.fColorUni, 0, 1, c);
485 fColor = color; 337 fColor = color;
486 } 338 }
487 sharedState->fConstAttribColorIndex = -1; 339 sharedState->fConstAttribColorIndex = -1;
488 break; 340 break;
489 case GrGLProgramDesc::kSolidWhite_ColorInput: 341 case GrGLProgramDesc::kSolidWhite_ColorInput:
490 case GrGLProgramDesc::kTransBlack_ColorInput: 342 case GrGLProgramDesc::kTransBlack_ColorInput:
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 406
555 fMatrixState.fViewMatrix = drawState.getViewMatrix(); 407 fMatrixState.fViewMatrix = drawState.getViewMatrix();
556 fMatrixState.fRenderTargetSize = size; 408 fMatrixState.fRenderTargetSize = size;
557 fMatrixState.fRenderTargetOrigin = rt->origin(); 409 fMatrixState.fRenderTargetOrigin = rt->origin();
558 410
559 GrGLfloat viewMatrix[3 * 3]; 411 GrGLfloat viewMatrix[3 * 3];
560 fMatrixState.getGLMatrix<3>(viewMatrix); 412 fMatrixState.getGLMatrix<3>(viewMatrix);
561 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, viewMatrix); 413 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, viewMatrix);
562 } 414 }
563 } 415 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698