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

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: rebase 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(header.fColorFilterXfermode,
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 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 coverage = drawState.getCoverage(); 269 coverage = drawState.getCoverage();
405 } else { 270 } else {
406 color = drawState.getColor(); 271 color = drawState.getColor();
407 coverage = drawState.getCoverage(); 272 coverage = drawState.getCoverage();
408 } 273 }
409 274
410 this->setColor(drawState, color, sharedState); 275 this->setColor(drawState, color, sharedState);
411 this->setCoverage(drawState, coverage, sharedState); 276 this->setCoverage(drawState, coverage, sharedState);
412 this->setMatrixAndRenderTargetHeight(drawState); 277 this->setMatrixAndRenderTargetHeight(drawState);
413 278
414 // Setup the SkXfermode::Mode-based colorfilter uniform if necessary
415 if (fUniformHandles.fColorFilterUni.isValid() &&
416 fColorFilterColor != drawState.getColorFilterColor()) {
417 GrGLfloat c[4];
418 GrColorToRGBAFloat(drawState.getColorFilterColor(), c);
419 fUniformManager.set4fv(fUniformHandles.fColorFilterUni, 0, 1, c);
420 fColorFilterColor = drawState.getColorFilterColor();
421 }
422
423 if (NULL != dstCopy) { 279 if (NULL != dstCopy) {
424 if (fUniformHandles.fDstCopyTopLeftUni.isValid()) { 280 if (fUniformHandles.fDstCopyTopLeftUni.isValid()) {
425 fUniformManager.set2f(fUniformHandles.fDstCopyTopLeftUni, 281 fUniformManager.set2f(fUniformHandles.fDstCopyTopLeftUni,
426 static_cast<GrGLfloat>(dstCopy->offset().fX), 282 static_cast<GrGLfloat>(dstCopy->offset().fX),
427 static_cast<GrGLfloat>(dstCopy->offset().fY)); 283 static_cast<GrGLfloat>(dstCopy->offset().fY));
428 fUniformManager.set2f(fUniformHandles.fDstCopyScaleUni, 284 fUniformManager.set2f(fUniformHandles.fDstCopyScaleUni,
429 1.f / dstCopy->texture()->width(), 285 1.f / dstCopy->texture()->width(),
430 1.f / dstCopy->texture()->height()); 286 1.f / dstCopy->texture()->height());
431 GrGLTexture* texture = static_cast<GrGLTexture*>(dstCopy->texture()) ; 287 GrGLTexture* texture = static_cast<GrGLTexture*>(dstCopy->texture()) ;
432 static GrTextureParams kParams; // the default is clamp, nearest fil tering. 288 static GrTextureParams kParams; // the default is clamp, nearest fil tering.
433 fGpu->bindTexture(fDstCopyTexUnit, kParams, texture); 289 fGpu->bindTexture(fDstCopyTexUnit, kParams, texture);
434 } else { 290 } else {
435 SkASSERT(!fUniformHandles.fDstCopyScaleUni.isValid()); 291 SkASSERT(!fUniformHandles.fDstCopyScaleUni.isValid());
436 SkASSERT(!fUniformHandles.fDstCopySamplerUni.isValid()); 292 SkASSERT(!fUniformHandles.fDstCopySamplerUni.isValid());
437 } 293 }
438 } else { 294 } else {
439 SkASSERT(!fUniformHandles.fDstCopyTopLeftUni.isValid()); 295 SkASSERT(!fUniformHandles.fDstCopyTopLeftUni.isValid());
440 SkASSERT(!fUniformHandles.fDstCopyScaleUni.isValid()); 296 SkASSERT(!fUniformHandles.fDstCopyScaleUni.isValid());
441 SkASSERT(!fUniformHandles.fDstCopySamplerUni.isValid()); 297 SkASSERT(!fUniformHandles.fDstCopySamplerUni.isValid());
442 } 298 }
443 299
444 for (int e = 0; e < fColorEffects.count(); ++e) { 300 for (int e = 0; e < fColorEffects.count(); ++e) {
445 // We may have omitted the GrGLEffect because of the color filter logic in genProgram. 301 SkASSERT(NULL != fColorEffects[e].fGLEffect);
446 // This can be removed when the color filter is an effect. 302 this->setEffectData(*colorStages[e], fColorEffects[e]);
447 if (NULL != fColorEffects[e].fGLEffect) {
448 this->setEffectData(*colorStages[e], fColorEffects[e]);
449 }
450 } 303 }
451 304
452 for (int e = 0; e < fCoverageEffects.count(); ++e) { 305 for (int e = 0; e < fCoverageEffects.count(); ++e) {
453 if (NULL != fCoverageEffects[e].fGLEffect) { 306 SkASSERT(NULL != fCoverageEffects[e].fGLEffect);
454 this->setEffectData(*coverageStages[e], fCoverageEffects[e]); 307 this->setEffectData(*coverageStages[e], fCoverageEffects[e]);
455 }
456 } 308 }
457 } 309 }
458 310
459 void GrGLProgram::setColor(const GrDrawState& drawState, 311 void GrGLProgram::setColor(const GrDrawState& drawState,
460 GrColor color, 312 GrColor color,
461 SharedGLState* sharedState) { 313 SharedGLState* sharedState) {
462 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); 314 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
463 if (!drawState.hasColorVertexAttribute()) { 315 if (!drawState.hasColorVertexAttribute()) {
464 switch (header.fColorInput) { 316 switch (header.fColorInput) {
465 case GrGLProgramDesc::kAttribute_ColorInput: 317 case GrGLProgramDesc::kAttribute_ColorInput:
466 SkASSERT(-1 != header.fColorAttributeIndex); 318 SkASSERT(-1 != header.fColorAttributeIndex);
467 if (sharedState->fConstAttribColor != color || 319 if (sharedState->fConstAttribColor != color ||
468 sharedState->fConstAttribColorIndex != header.fColorAttribut eIndex) { 320 sharedState->fConstAttribColorIndex != header.fColorAttribut eIndex) {
469 // OpenGL ES only supports the float varieties of glVertexAt trib 321 // OpenGL ES only supports the float varieties of glVertexAt trib
470 GrGLfloat c[4]; 322 GrGLfloat c[4];
471 GrColorToRGBAFloat(color, c); 323 GrColorToRGBAFloat(color, c);
472 GL_CALL(VertexAttrib4fv(header.fColorAttributeIndex, c)); 324 GL_CALL(VertexAttrib4fv(header.fColorAttributeIndex, c));
473 sharedState->fConstAttribColor = color; 325 sharedState->fConstAttribColor = color;
474 sharedState->fConstAttribColorIndex = header.fColorAttribute Index; 326 sharedState->fConstAttribColorIndex = header.fColorAttribute Index;
475 } 327 }
476 break; 328 break;
477 case GrGLProgramDesc::kUniform_ColorInput: 329 case GrGLProgramDesc::kUniform_ColorInput:
478 if (fColor != color) { 330 if (fColor != color && fUniformHandles.fColorUni.isValid()) {
479 // OpenGL ES doesn't support unsigned byte varieties of glUn iform 331 // OpenGL ES doesn't support unsigned byte varieties of glUn iform
480 GrGLfloat c[4]; 332 GrGLfloat c[4];
481 GrColorToRGBAFloat(color, c); 333 GrColorToRGBAFloat(color, c);
482 fUniformManager.set4fv(fUniformHandles.fColorUni, 0, 1, c); 334 fUniformManager.set4fv(fUniformHandles.fColorUni, 0, 1, c);
483 fColor = color; 335 fColor = color;
484 } 336 }
485 sharedState->fConstAttribColorIndex = -1; 337 sharedState->fConstAttribColorIndex = -1;
486 break; 338 break;
487 case GrGLProgramDesc::kSolidWhite_ColorInput: 339 case GrGLProgramDesc::kSolidWhite_ColorInput:
488 case GrGLProgramDesc::kTransBlack_ColorInput: 340 case GrGLProgramDesc::kTransBlack_ColorInput:
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 404
553 fMatrixState.fViewMatrix = drawState.getViewMatrix(); 405 fMatrixState.fViewMatrix = drawState.getViewMatrix();
554 fMatrixState.fRenderTargetSize = size; 406 fMatrixState.fRenderTargetSize = size;
555 fMatrixState.fRenderTargetOrigin = rt->origin(); 407 fMatrixState.fRenderTargetOrigin = rt->origin();
556 408
557 GrGLfloat viewMatrix[3 * 3]; 409 GrGLfloat viewMatrix[3 * 3];
558 fMatrixState.getGLMatrix<3>(viewMatrix); 410 fMatrixState.getGLMatrix<3>(viewMatrix);
559 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, viewMatrix); 411 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, viewMatrix);
560 } 412 }
561 } 413 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698