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

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: address review comments 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
« no previous file with comments | « src/gpu/gl/GrGLProgram.h ('k') | src/gpu/gl/GrGLProgramDesc.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 30 matching lines...) Expand all
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->shouldUseFixedFunctionTexturing()) { 53 !fGpu->shouldUseFixedFunctionTexturing()) {
55 GrGLFullShaderBuilder fullBuilder(fGpu, fUniformManager, fDesc); 54 GrGLFullShaderBuilder fullBuilder(fGpu, fUniformManager, fDesc);
56 if (this->genProgram(&fullBuilder, colorStages, coverageStages)) { 55 if (this->genProgram(&fullBuilder, colorStages, coverageStages)) {
57 fUniformHandles.fViewMatrixUni = fullBuilder.getViewMatrixUniform(); 56 fUniformHandles.fViewMatrixUni = fullBuilder.getViewMatrixUniform();
58 fHasVertexShader = true; 57 fHasVertexShader = true;
59 } 58 }
60 } else { 59 } else {
61 GrGLFragmentOnlyShaderBuilder fragmentOnlyBuilder(fGpu, fUniformManager, fDesc); 60 GrGLFragmentOnlyShaderBuilder fragmentOnlyBuilder(fGpu, fUniformManager, fDesc);
(...skipping 28 matching lines...) Expand all
90 case GrGLProgramDesc::kCombineWithDst_CoverageOutput: 89 case GrGLProgramDesc::kCombineWithDst_CoverageOutput:
91 // We should only have set this if the blend was specified as (1, 0) 90 // We should only have set this if the blend was specified as (1, 0)
92 SkASSERT(kOne_GrBlendCoeff == *srcCoeff && kZero_GrBlendCoeff == *ds tCoeff); 91 SkASSERT(kOne_GrBlendCoeff == *srcCoeff && kZero_GrBlendCoeff == *ds tCoeff);
93 break; 92 break;
94 default: 93 default:
95 GrCrash("Unexpected coverage output"); 94 GrCrash("Unexpected coverage output");
96 break; 95 break;
97 } 96 }
98 } 97 }
99 98
100 namespace {
101 // given two blend coefficients determine whether the src
102 // and/or dst computation can be omitted.
103 inline void need_blend_inputs(SkXfermode::Coeff srcCoeff,
104 SkXfermode::Coeff dstCoeff,
105 bool* needSrcValue,
106 bool* needDstValue) {
107 if (SkXfermode::kZero_Coeff == srcCoeff) {
108 switch (dstCoeff) {
109 // these all read the src
110 case SkXfermode::kSC_Coeff:
111 case SkXfermode::kISC_Coeff:
112 case SkXfermode::kSA_Coeff:
113 case SkXfermode::kISA_Coeff:
114 *needSrcValue = true;
115 break;
116 default:
117 *needSrcValue = false;
118 break;
119 }
120 } else {
121 *needSrcValue = true;
122 }
123 if (SkXfermode::kZero_Coeff == dstCoeff) {
124 switch (srcCoeff) {
125 // these all read the dst
126 case SkXfermode::kDC_Coeff:
127 case SkXfermode::kIDC_Coeff:
128 case SkXfermode::kDA_Coeff:
129 case SkXfermode::kIDA_Coeff:
130 *needDstValue = true;
131 break;
132 default:
133 *needDstValue = false;
134 break;
135 }
136 } else {
137 *needDstValue = true;
138 }
139 }
140
141 /**
142 * Create a blend_coeff * value string to be used in shader code. Sets empty
143 * string if result is trivially zero.
144 */
145 inline void blend_term_string(SkString* str, SkXfermode::Coeff coeff,
146 const char* src, const char* dst,
147 const char* value) {
148 switch (coeff) {
149 case SkXfermode::kZero_Coeff: /** 0 */
150 *str = "";
151 break;
152 case SkXfermode::kOne_Coeff: /** 1 */
153 *str = value;
154 break;
155 case SkXfermode::kSC_Coeff:
156 str->printf("(%s * %s)", src, value);
157 break;
158 case SkXfermode::kISC_Coeff:
159 str->printf("((vec4(1) - %s) * %s)", src, value);
160 break;
161 case SkXfermode::kDC_Coeff:
162 str->printf("(%s * %s)", dst, value);
163 break;
164 case SkXfermode::kIDC_Coeff:
165 str->printf("((vec4(1) - %s) * %s)", dst, value);
166 break;
167 case SkXfermode::kSA_Coeff: /** src alpha */
168 str->printf("(%s.a * %s)", src, value);
169 break;
170 case SkXfermode::kISA_Coeff: /** inverse src alpha (i.e. 1 - sa) */
171 str->printf("((1.0 - %s.a) * %s)", src, value);
172 break;
173 case SkXfermode::kDA_Coeff: /** dst alpha */
174 str->printf("(%s.a * %s)", dst, value);
175 break;
176 case SkXfermode::kIDA_Coeff: /** inverse dst alpha (i.e. 1 - da) */
177 str->printf("((1.0 - %s.a) * %s)", dst, value);
178 break;
179 default:
180 GrCrash("Unexpected xfer coeff.");
181 break;
182 }
183 }
184 /**
185 * Adds a line to the fragment shader code which modifies the color by
186 * the specified color filter.
187 */
188 void add_color_filter(GrGLShaderBuilder* builder,
189 const char * outputVar,
190 SkXfermode::Coeff uniformCoeff,
191 SkXfermode::Coeff colorCoeff,
192 const char* filterColor,
193 const char* inColor) {
194 SkString colorStr, constStr;
195 blend_term_string(&colorStr, colorCoeff, filterColor, inColor, inColor);
196 blend_term_string(&constStr, uniformCoeff, filterColor, inColor, filterColor );
197 GrGLSLExpr<4> sum;
198 if (colorStr.isEmpty() && constStr.isEmpty()) {
199 sum = GrGLSLExpr<4>(0);
200 } else if (colorStr.isEmpty()) {
201 sum = constStr;
202 } else if (constStr.isEmpty()) {
203 sum = colorStr;
204 } else {
205 sum = GrGLSLExpr<4>(colorStr) + GrGLSLExpr<4>(constStr);
206 }
207 builder->fsCodeAppendf("\t%s = %s;\n", outputVar, sum.c_str());
208 }
209 }
210
211 bool GrGLProgram::genProgram(GrGLShaderBuilder* builder, 99 bool GrGLProgram::genProgram(GrGLShaderBuilder* builder,
212 const GrEffectStage* colorStages[], 100 const GrEffectStage* colorStages[],
213 const GrEffectStage* coverageStages[]) { 101 const GrEffectStage* coverageStages[]) {
214 SkASSERT(0 == fProgramID); 102 SkASSERT(0 == fProgramID);
215 103
216 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); 104 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
217 105
218 // incoming color to current stage being processed. 106 // incoming color to current stage being processed.
219 GrGLSLExpr<4> inColor = builder->getInputColor(); 107 GrGLSLExpr4 inColor = builder->getInputColor();
220
221 // Get the coeffs for the Mode-based color filter, determine if color is nee ded.
222 SkXfermode::Coeff colorCoeff;
223 SkXfermode::Coeff filterColorCoeff;
224 SkAssertResult(
225 SkXfermode::ModeAsCoeff(header.fColorFilterXfermode,
226 &filterColorCoeff,
227 &colorCoeff));
228 bool needColor, needFilterColor;
229 need_blend_inputs(filterColorCoeff, colorCoeff, &needFilterColor, &needColor );
230 108
231 fColorEffects.reset( 109 fColorEffects.reset(
232 builder->createAndEmitEffects(colorStages, 110 builder->createAndEmitEffects(colorStages,
233 fDesc.effectKeys(), 111 fDesc.effectKeys(),
234 needColor ? fDesc.numColorEffects() : 0, 112 fDesc.numColorEffects(),
235 &inColor)); 113 &inColor));
236 114
237 // Insert the color filter. This will soon be replaced by a color effect.
238 if (SkXfermode::kDst_Mode != header.fColorFilterXfermode) {
239 const char* colorFilterColorUniName = NULL;
240 fUniformHandles.fColorFilterUni = builder->addUniform(GrGLShaderBuilder: :kFragment_Visibility,
241 kVec4f_GrSLType, " FilterColor",
242 &colorFilterColorU niName);
243
244 builder->fsCodeAppend("\tvec4 filteredColor;\n");
245 add_color_filter(builder, "filteredColor", filterColorCoeff,
246 colorCoeff, colorFilterColorUniName, inColor.c_str());
247 inColor = "filteredColor";
248 }
249
250 /////////////////////////////////////////////////////////////////////////// 115 ///////////////////////////////////////////////////////////////////////////
251 // compute the partial coverage 116 // compute the partial coverage
252 GrGLSLExpr<4> inCoverage = builder->getInputCoverage(); 117 GrGLSLExpr4 inCoverage = builder->getInputCoverage();
253 118
254 fCoverageEffects.reset( 119 fCoverageEffects.reset(
255 builder->createAndEmitEffects(coverageStages, 120 builder->createAndEmitEffects(coverageStages,
256 fDesc.getEffectKeys() + fDesc.numColorEffe cts(), 121 fDesc.getEffectKeys() + fDesc.numColorEffe cts(),
257 fDesc.numCoverageEffects(), 122 fDesc.numCoverageEffects(),
258 &inCoverage)); 123 &inCoverage));
259 124
260 // discard if coverage is zero 125 // discard if coverage is zero
261 if (header.fDiscardIfZeroCoverage && !inCoverage.isOnes()) { 126 if (header.fDiscardIfZeroCoverage && !inCoverage.isOnes()) {
262 if (inCoverage.isZeros()) { 127 if (inCoverage.isZeros()) {
263 // This is unfortunate. 128 // This is unfortunate.
264 builder->fsCodeAppend("\tdiscard;\n"); 129 builder->fsCodeAppend("\tdiscard;\n");
265 } else { 130 } else {
266 builder->fsCodeAppendf("\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n \t\tdiscard;\n\t}\n", 131 builder->fsCodeAppendf("\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n \t\tdiscard;\n\t}\n",
267 inCoverage.c_str()); 132 inCoverage.c_str());
268 } 133 }
269 } 134 }
270 135
271 if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(header.fCoverageOutpu t)) { 136 if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(header.fCoverageOutpu t)) {
272 const char* secondaryOutputName = builder->enableSecondaryOutput(); 137 const char* secondaryOutputName = builder->enableSecondaryOutput();
273 138
274 // default coeff to ones for kCoverage_DualSrcOutput 139 // default coeff to ones for kCoverage_DualSrcOutput
275 GrGLSLExpr<4> coeff(1); 140 GrGLSLExpr4 coeff(1);
276 if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCov erageOutput) { 141 if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCov erageOutput) {
277 // Get (1-A) into coeff 142 // Get (1-A) into coeff
278 coeff = GrGLSLExprCast4(GrGLSLExpr<1>(1) - GrGLSLExprExtractAlpha(in Color)); 143 coeff = GrGLSLExpr4::VectorCast(GrGLSLExpr1(1) - inColor.a());
279 } else if (GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput == head er.fCoverageOutput) { 144 } else if (GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput == head er.fCoverageOutput) {
280 // Get (1-RGBA) into coeff 145 // Get (1-RGBA) into coeff
281 coeff = GrGLSLExpr<4>(1) - inColor; 146 coeff = GrGLSLExpr4(1) - inColor;
282 } 147 }
283 // Get coeff * coverage into modulate and then write that to the dual so urce output. 148 // Get coeff * coverage into modulate and then write that to the dual so urce output.
284 builder->fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, (coeff * inC overage).c_str()); 149 builder->fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, (coeff * inC overage).c_str());
285 } 150 }
286 151
287 /////////////////////////////////////////////////////////////////////////// 152 ///////////////////////////////////////////////////////////////////////////
288 // combine color and coverage as frag color 153 // combine color and coverage as frag color
289 154
290 // Get "color * coverage" into fragColor 155 // Get "color * coverage" into fragColor
291 GrGLSLExpr<4> fragColor = inColor * inCoverage; 156 GrGLSLExpr4 fragColor = inColor * inCoverage;
292 // Now tack on "+(1-coverage)dst onto the frag color if we were asked to do so. 157 // Now tack on "+(1-coverage)dst onto the frag color if we were asked to do so.
293 if (GrGLProgramDesc::kCombineWithDst_CoverageOutput == header.fCoverageOutpu t) { 158 if (GrGLProgramDesc::kCombineWithDst_CoverageOutput == header.fCoverageOutpu t) {
294 GrGLSLExpr<4> dstCoeff = GrGLSLExpr<4>(1) - inCoverage; 159 GrGLSLExpr4 dstCoeff = GrGLSLExpr4(1) - inCoverage;
295 160
296 GrGLSLExpr<4> dstContribution = dstCoeff * GrGLSLExpr<4>(builder->dstCol or()); 161 GrGLSLExpr4 dstContribution = dstCoeff * GrGLSLExpr4(builder->dstColor() );
297 162
298 fragColor = fragColor + dstContribution; 163 fragColor = fragColor + dstContribution;
299 } 164 }
300 builder->fsCodeAppendf("\t%s = %s;\n", builder->getColorOutputName(), fragCo lor.c_str()); 165 builder->fsCodeAppendf("\t%s = %s;\n", builder->getColorOutputName(), fragCo lor.c_str());
301 166
302 if (!builder->finish(&fProgramID)) { 167 if (!builder->finish(&fProgramID)) {
303 return false; 168 return false;
304 } 169 }
305 170
306 fUniformHandles.fRTHeightUni = builder->getRTHeightUniform(); 171 fUniformHandles.fRTHeightUni = builder->getRTHeightUniform();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 coverage = drawState.getCoverage(); 210 coverage = drawState.getCoverage();
346 } else { 211 } else {
347 color = drawState.getColor(); 212 color = drawState.getColor();
348 coverage = drawState.getCoverage(); 213 coverage = drawState.getCoverage();
349 } 214 }
350 215
351 this->setColor(drawState, color, sharedState); 216 this->setColor(drawState, color, sharedState);
352 this->setCoverage(drawState, coverage, sharedState); 217 this->setCoverage(drawState, coverage, sharedState);
353 this->setMatrixAndRenderTargetHeight(drawState); 218 this->setMatrixAndRenderTargetHeight(drawState);
354 219
355 // Setup the SkXfermode::Mode-based colorfilter uniform if necessary
356 if (fUniformHandles.fColorFilterUni.isValid() &&
357 fColorFilterColor != drawState.getColorFilterColor()) {
358 GrGLfloat c[4];
359 GrColorToRGBAFloat(drawState.getColorFilterColor(), c);
360 fUniformManager.set4fv(fUniformHandles.fColorFilterUni, 0, 1, c);
361 fColorFilterColor = drawState.getColorFilterColor();
362 }
363
364 if (NULL != dstCopy) { 220 if (NULL != dstCopy) {
365 if (fUniformHandles.fDstCopyTopLeftUni.isValid()) { 221 if (fUniformHandles.fDstCopyTopLeftUni.isValid()) {
366 fUniformManager.set2f(fUniformHandles.fDstCopyTopLeftUni, 222 fUniformManager.set2f(fUniformHandles.fDstCopyTopLeftUni,
367 static_cast<GrGLfloat>(dstCopy->offset().fX), 223 static_cast<GrGLfloat>(dstCopy->offset().fX),
368 static_cast<GrGLfloat>(dstCopy->offset().fY)); 224 static_cast<GrGLfloat>(dstCopy->offset().fY));
369 fUniformManager.set2f(fUniformHandles.fDstCopyScaleUni, 225 fUniformManager.set2f(fUniformHandles.fDstCopyScaleUni,
370 1.f / dstCopy->texture()->width(), 226 1.f / dstCopy->texture()->width(),
371 1.f / dstCopy->texture()->height()); 227 1.f / dstCopy->texture()->height());
372 GrGLTexture* texture = static_cast<GrGLTexture*>(dstCopy->texture()) ; 228 GrGLTexture* texture = static_cast<GrGLTexture*>(dstCopy->texture()) ;
373 static GrTextureParams kParams; // the default is clamp, nearest fil tering. 229 static GrTextureParams kParams; // the default is clamp, nearest fil tering.
(...skipping 28 matching lines...) Expand all
402 sharedState->fConstAttribColorIndex != header.fColorAttribut eIndex) { 258 sharedState->fConstAttribColorIndex != header.fColorAttribut eIndex) {
403 // OpenGL ES only supports the float varieties of glVertexAt trib 259 // OpenGL ES only supports the float varieties of glVertexAt trib
404 GrGLfloat c[4]; 260 GrGLfloat c[4];
405 GrColorToRGBAFloat(color, c); 261 GrColorToRGBAFloat(color, c);
406 GL_CALL(VertexAttrib4fv(header.fColorAttributeIndex, c)); 262 GL_CALL(VertexAttrib4fv(header.fColorAttributeIndex, c));
407 sharedState->fConstAttribColor = color; 263 sharedState->fConstAttribColor = color;
408 sharedState->fConstAttribColorIndex = header.fColorAttribute Index; 264 sharedState->fConstAttribColorIndex = header.fColorAttribute Index;
409 } 265 }
410 break; 266 break;
411 case GrGLProgramDesc::kUniform_ColorInput: 267 case GrGLProgramDesc::kUniform_ColorInput:
412 if (fColor != color) { 268 if (fColor != color && fUniformHandles.fColorUni.isValid()) {
413 // OpenGL ES doesn't support unsigned byte varieties of glUn iform 269 // OpenGL ES doesn't support unsigned byte varieties of glUn iform
414 GrGLfloat c[4]; 270 GrGLfloat c[4];
415 GrColorToRGBAFloat(color, c); 271 GrColorToRGBAFloat(color, c);
416 fUniformManager.set4fv(fUniformHandles.fColorUni, 0, 1, c); 272 fUniformManager.set4fv(fUniformHandles.fColorUni, 0, 1, c);
417 fColor = color; 273 fColor = color;
418 } 274 }
419 sharedState->fConstAttribColorIndex = -1; 275 sharedState->fConstAttribColorIndex = -1;
420 break; 276 break;
421 case GrGLProgramDesc::kSolidWhite_ColorInput: 277 case GrGLProgramDesc::kSolidWhite_ColorInput:
422 case GrGLProgramDesc::kTransBlack_ColorInput: 278 case GrGLProgramDesc::kTransBlack_ColorInput:
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 346
491 fMatrixState.fViewMatrix = drawState.getViewMatrix(); 347 fMatrixState.fViewMatrix = drawState.getViewMatrix();
492 fMatrixState.fRenderTargetSize = size; 348 fMatrixState.fRenderTargetSize = size;
493 fMatrixState.fRenderTargetOrigin = rt->origin(); 349 fMatrixState.fRenderTargetOrigin = rt->origin();
494 350
495 GrGLfloat viewMatrix[3 * 3]; 351 GrGLfloat viewMatrix[3 * 3];
496 fMatrixState.getGLMatrix<3>(viewMatrix); 352 fMatrixState.getGLMatrix<3>(viewMatrix);
497 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, viewMatrix); 353 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, viewMatrix);
498 } 354 }
499 } 355 }
OLDNEW
« no previous file with comments | « src/gpu/gl/GrGLProgram.h ('k') | src/gpu/gl/GrGLProgramDesc.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698