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

Side by Side Diff: src/gpu/gl/GrGLProgramDesc.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/GrGLProgramDesc.h ('k') | src/gpu/gl/GrGLSL.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 2013 Google Inc. 2 * Copyright 2013 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 "GrGLProgramDesc.h" 8 #include "GrGLProgramDesc.h"
9 #include "GrBackendEffectFactory.h" 9 #include "GrBackendEffectFactory.h"
10 #include "GrDrawEffect.h" 10 #include "GrDrawEffect.h"
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 colorStages->reset(); 49 colorStages->reset();
50 coverageStages->reset(); 50 coverageStages->reset();
51 51
52 // This should already have been caught 52 // This should already have been caught
53 SkASSERT(!(GrDrawState::kSkipDraw_BlendOptFlag & blendOpts)); 53 SkASSERT(!(GrDrawState::kSkipDraw_BlendOptFlag & blendOpts));
54 54
55 bool skipCoverage = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_BlendO ptFlag); 55 bool skipCoverage = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_BlendO ptFlag);
56 56
57 bool skipColor = SkToBool(blendOpts & (GrDrawState::kEmitTransBlack_BlendOpt Flag | 57 bool skipColor = SkToBool(blendOpts & (GrDrawState::kEmitTransBlack_BlendOpt Flag |
58 GrDrawState::kEmitCoverage_BlendOptFl ag)); 58 GrDrawState::kEmitCoverage_BlendOptFl ag));
59 int firstEffectiveColorStage = 0;
60 bool inputColorIsUsed = true;
61 if (!skipColor) {
62 firstEffectiveColorStage = drawState.numColorStages();
63 while (firstEffectiveColorStage > 0 && inputColorIsUsed) {
64 --firstEffectiveColorStage;
65 const GrEffect* effect = drawState.getColorStage(firstEffectiveColor Stage).getEffect()->get();
66 inputColorIsUsed = effect->willUseInputColor();
67 }
68 }
69
70 int firstEffectiveCoverageStage = 0;
71 bool inputCoverageIsUsed = true;
72 if (!skipCoverage) {
73 firstEffectiveCoverageStage = drawState.numCoverageStages();
74 while (firstEffectiveCoverageStage > 0 && inputCoverageIsUsed) {
75 --firstEffectiveCoverageStage;
76 const GrEffect* effect = drawState.getCoverageStage(firstEffectiveCo verageStage).getEffect()->get();
77 inputCoverageIsUsed = effect->willUseInputColor();
78 }
79 }
59 80
60 // The descriptor is used as a cache key. Thus when a field of the 81 // The descriptor is used as a cache key. Thus when a field of the
61 // descriptor will not affect program generation (because of the attribute 82 // descriptor will not affect program generation (because of the attribute
62 // bindings in use or other descriptor field settings) it should be set 83 // bindings in use or other descriptor field settings) it should be set
63 // to a canonical value to avoid duplicate programs with different keys. 84 // to a canonical value to avoid duplicate programs with different keys.
64 85
65 bool requiresColorAttrib = !skipColor && drawState.hasColorVertexAttribute() ; 86 bool requiresColorAttrib = !skipColor && drawState.hasColorVertexAttribute() ;
66 bool requiresCoverageAttrib = !skipCoverage && drawState.hasCoverageVertexAt tribute(); 87 bool requiresCoverageAttrib = !skipCoverage && drawState.hasCoverageVertexAt tribute();
67 // we only need the local coords if we're actually going to generate effect code 88 // we only need the local coords if we're actually going to generate effect code
68 bool requiresLocalCoordAttrib = !(skipCoverage && skipColor) && 89 bool requiresLocalCoordAttrib = !(skipCoverage && skipColor) &&
69 drawState.hasLocalCoordAttribute(); 90 drawState.hasLocalCoordAttribute();
70 91
71 bool colorIsTransBlack = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_B lendOptFlag); 92 bool colorIsTransBlack = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_B lendOptFlag);
72 bool colorIsSolidWhite = (blendOpts & GrDrawState::kEmitCoverage_BlendOptFla g) || 93 bool colorIsSolidWhite = (blendOpts & GrDrawState::kEmitCoverage_BlendOptFla g) ||
73 (!requiresColorAttrib && 0xffffffff == drawState.ge tColor()); 94 (!requiresColorAttrib && 0xffffffff == drawState.ge tColor()) ||
95 (!inputColorIsUsed);
74 96
75 int numEffects = (skipColor ? 0 : drawState.numColorStages()) + 97 int numEffects = (skipColor ? 0 : (drawState.numColorStages() - firstEffecti veColorStage)) +
76 (skipCoverage ? 0 : drawState.numCoverageStages()); 98 (skipCoverage ? 0 : (drawState.numCoverageStages() - firstE ffectiveCoverageStage));
77 99
78 size_t newKeyLength = KeyLength(numEffects); 100 size_t newKeyLength = KeyLength(numEffects);
79 bool allocChanged; 101 bool allocChanged;
80 desc->fKey.reset(newKeyLength, SkAutoMalloc::kAlloc_OnShrink, &allocChanged) ; 102 desc->fKey.reset(newKeyLength, SkAutoMalloc::kAlloc_OnShrink, &allocChanged) ;
81 if (allocChanged || !desc->fInitialized) { 103 if (allocChanged || !desc->fInitialized) {
82 // make sure any padding in the header is zero if we we haven't used thi s allocation before. 104 // make sure any padding in the header is zero if we we haven't used thi s allocation before.
83 memset(desc->header(), 0, kHeaderSize); 105 memset(desc->header(), 0, kHeaderSize);
84 } 106 }
85 // write the key length 107 // write the key length
86 *desc->atOffset<uint32_t, kLengthOffset>() = newKeyLength; 108 *desc->atOffset<uint32_t, kLengthOffset>() = newKeyLength;
87 109
88 KeyHeader* header = desc->header(); 110 KeyHeader* header = desc->header();
89 EffectKey* effectKeys = desc->effectKeys(); 111 EffectKey* effectKeys = desc->effectKeys();
90 112
91 int currEffectKey = 0; 113 int currEffectKey = 0;
92 bool readsDst = false; 114 bool readsDst = false;
93 bool readFragPosition = false; 115 bool readFragPosition = false;
94 bool hasVertexCode = false; 116 bool hasVertexCode = false;
95 if (!skipColor) { 117 if (!skipColor) {
96 for (int s = 0; s < drawState.numColorStages(); ++s) { 118 for (int s = firstEffectiveColorStage; s < drawState.numColorStages(); + +s) {
97 effectKeys[currEffectKey++] = 119 effectKeys[currEffectKey++] =
98 get_key_and_update_stats(drawState.getColorStage(s), gpu->glCaps (), 120 get_key_and_update_stats(drawState.getColorStage(s), gpu->glCaps (),
99 requiresLocalCoordAttrib, &readsDst, &r eadFragPosition, 121 requiresLocalCoordAttrib, &readsDst, &r eadFragPosition,
100 &hasVertexCode); 122 &hasVertexCode);
101 } 123 }
102 } 124 }
103 if (!skipCoverage) { 125 if (!skipCoverage) {
104 for (int s = 0; s < drawState.numCoverageStages(); ++s) { 126 for (int s = firstEffectiveCoverageStage; s < drawState.numCoverageStage s(); ++s) {
105 effectKeys[currEffectKey++] = 127 effectKeys[currEffectKey++] =
106 get_key_and_update_stats(drawState.getCoverageStage(s), gpu->glC aps(), 128 get_key_and_update_stats(drawState.getCoverageStage(s), gpu->glC aps(),
107 requiresLocalCoordAttrib, &readsDst, &r eadFragPosition, 129 requiresLocalCoordAttrib, &readsDst, &r eadFragPosition,
108 &hasVertexCode); 130 &hasVertexCode);
109 } 131 }
110 } 132 }
111 133
112 header->fHasVertexCode = hasVertexCode || requiresLocalCoordAttrib; 134 header->fHasVertexCode = hasVertexCode || requiresLocalCoordAttrib;
113 header->fEmitsPointSize = isPoints; 135 header->fEmitsPointSize = isPoints;
114 header->fColorFilterXfermode = skipColor ? SkXfermode::kDst_Mode : drawState .getColorFilterMode();
115 136
116 // Currently the experimental GS will only work with triangle prims (and it doesn't do anything 137 // Currently the experimental GS will only work with triangle prims (and it doesn't do anything
117 // other than pass through values from the VS to the FS anyway). 138 // other than pass through values from the VS to the FS anyway).
118 #if GR_GL_EXPERIMENTAL_GS 139 #if GR_GL_EXPERIMENTAL_GS
119 #if 0 140 #if 0
120 header->fExperimentalGS = gpu->caps().geometryShaderSupport(); 141 header->fExperimentalGS = gpu->caps().geometryShaderSupport();
121 #else 142 #else
122 header->fExperimentalGS = false; 143 header->fExperimentalGS = false;
123 #endif 144 #endif
124 #endif 145 #endif
125 bool defaultToUniformInputs = GR_GL_NO_CONSTANT_ATTRIBUTES || gpu->caps()->p athRenderingSupport(); 146 bool defaultToUniformInputs = GR_GL_NO_CONSTANT_ATTRIBUTES || gpu->caps()->p athRenderingSupport();
126 147
127 if (colorIsTransBlack) { 148 if (colorIsTransBlack) {
128 header->fColorInput = kTransBlack_ColorInput; 149 header->fColorInput = kTransBlack_ColorInput;
129 } else if (colorIsSolidWhite) { 150 } else if (colorIsSolidWhite) {
130 header->fColorInput = kSolidWhite_ColorInput; 151 header->fColorInput = kSolidWhite_ColorInput;
131 } else if (defaultToUniformInputs && !requiresColorAttrib) { 152 } else if (defaultToUniformInputs && !requiresColorAttrib) {
132 header->fColorInput = kUniform_ColorInput; 153 header->fColorInput = kUniform_ColorInput;
133 } else { 154 } else {
134 header->fColorInput = kAttribute_ColorInput; 155 header->fColorInput = kAttribute_ColorInput;
135 header->fHasVertexCode = true; 156 header->fHasVertexCode = true;
136 } 157 }
137 158
138 bool covIsSolidWhite = !requiresCoverageAttrib && 0xffffffff == drawState.ge tCoverage(); 159 bool covIsSolidWhite = !requiresCoverageAttrib && 0xffffffff == drawState.ge tCoverage();
139 160
140 if (skipCoverage) { 161 if (skipCoverage) {
141 header->fCoverageInput = kTransBlack_ColorInput; 162 header->fCoverageInput = kTransBlack_ColorInput;
142 } else if (covIsSolidWhite) { 163 } else if (covIsSolidWhite || !inputCoverageIsUsed) {
143 header->fCoverageInput = kSolidWhite_ColorInput; 164 header->fCoverageInput = kSolidWhite_ColorInput;
144 } else if (defaultToUniformInputs && !requiresCoverageAttrib) { 165 } else if (defaultToUniformInputs && !requiresCoverageAttrib) {
145 header->fCoverageInput = kUniform_ColorInput; 166 header->fCoverageInput = kUniform_ColorInput;
146 } else { 167 } else {
147 header->fCoverageInput = kAttribute_ColorInput; 168 header->fCoverageInput = kAttribute_ColorInput;
148 header->fHasVertexCode = true; 169 header->fHasVertexCode = true;
149 } 170 }
150 171
151 if (readsDst) { 172 if (readsDst) {
152 SkASSERT(NULL != dstCopy || gpu->caps()->dstReadInShaderSupport()); 173 SkASSERT(NULL != dstCopy || gpu->caps()->dstReadInShaderSupport());
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 // Here we deal with whether/how we handle color and coverage separately. 216 // Here we deal with whether/how we handle color and coverage separately.
196 217
197 // Set these defaults and then possibly change our mind if there is coverage . 218 // Set these defaults and then possibly change our mind if there is coverage .
198 header->fDiscardIfZeroCoverage = false; 219 header->fDiscardIfZeroCoverage = false;
199 header->fCoverageOutput = kModulate_CoverageOutput; 220 header->fCoverageOutput = kModulate_CoverageOutput;
200 221
201 // If we do have coverage determine whether it matters. 222 // If we do have coverage determine whether it matters.
202 bool separateCoverageFromColor = false; 223 bool separateCoverageFromColor = false;
203 if (!drawState.isCoverageDrawing() && !skipCoverage && 224 if (!drawState.isCoverageDrawing() && !skipCoverage &&
204 (drawState.numCoverageStages() > 0 || requiresCoverageAttrib)) { 225 (drawState.numCoverageStages() > 0 || requiresCoverageAttrib)) {
205 // color filter is applied between color/coverage computation
206 if (SkXfermode::kDst_Mode != header->fColorFilterXfermode) {
207 separateCoverageFromColor = true;
208 }
209 226
210 // If we're stenciling then we want to discard samples that have zero co verage 227 // If we're stenciling then we want to discard samples that have zero co verage
211 if (drawState.getStencil().doesWrite()) { 228 if (drawState.getStencil().doesWrite()) {
212 header->fDiscardIfZeroCoverage = true; 229 header->fDiscardIfZeroCoverage = true;
213 separateCoverageFromColor = true; 230 separateCoverageFromColor = true;
214 } 231 }
215 232
216 if (gpu->caps()->dualSourceBlendingSupport() && 233 if (gpu->caps()->dualSourceBlendingSupport() &&
217 !(blendOpts & (GrDrawState::kEmitCoverage_BlendOptFlag | 234 !(blendOpts & (GrDrawState::kEmitCoverage_BlendOptFlag |
218 GrDrawState::kCoverageAsAlpha_BlendOptFlag))) { 235 GrDrawState::kCoverageAsAlpha_BlendOptFlag))) {
(...skipping 11 matching lines...) Expand all
230 separateCoverageFromColor = true; 247 separateCoverageFromColor = true;
231 } 248 }
232 } else if (readsDst && 249 } else if (readsDst &&
233 kOne_GrBlendCoeff == srcCoeff && 250 kOne_GrBlendCoeff == srcCoeff &&
234 kZero_GrBlendCoeff == dstCoeff) { 251 kZero_GrBlendCoeff == dstCoeff) {
235 header->fCoverageOutput = kCombineWithDst_CoverageOutput; 252 header->fCoverageOutput = kCombineWithDst_CoverageOutput;
236 separateCoverageFromColor = true; 253 separateCoverageFromColor = true;
237 } 254 }
238 } 255 }
239 if (!skipColor) { 256 if (!skipColor) {
240 for (int s = 0; s < drawState.numColorStages(); ++s) { 257 for (int s = firstEffectiveColorStage; s < drawState.numColorStages(); + +s) {
241 colorStages->push_back(&drawState.getColorStage(s)); 258 colorStages->push_back(&drawState.getColorStage(s));
242 } 259 }
243 header->fColorEffectCnt = drawState.numColorStages();
244 } 260 }
245 if (!skipCoverage) { 261 if (!skipCoverage) {
246 SkTArray<const GrEffectStage*, true>* array; 262 SkTArray<const GrEffectStage*, true>* array;
247 if (separateCoverageFromColor) { 263 if (separateCoverageFromColor) {
248 array = coverageStages; 264 array = coverageStages;
249 header->fCoverageEffectCnt = drawState.numCoverageStages();
250 } else { 265 } else {
251 array = colorStages; 266 array = colorStages;
252 header->fColorEffectCnt += drawState.numCoverageStages();
253 } 267 }
254 for (int s = 0; s < drawState.numCoverageStages(); ++s) { 268 for (int s = firstEffectiveCoverageStage; s < drawState.numCoverageStage s(); ++s) {
255 array->push_back(&drawState.getCoverageStage(s)); 269 array->push_back(&drawState.getCoverageStage(s));
256 } 270 }
257 } 271 }
272 header->fColorEffectCnt = colorStages->count();
273 header->fCoverageEffectCnt = coverageStages->count();
258 274
259 *desc->checksum() = 0; 275 *desc->checksum() = 0;
260 *desc->checksum() = SkChecksum::Compute(reinterpret_cast<uint32_t*>(desc->fK ey.get()), 276 *desc->checksum() = SkChecksum::Compute(reinterpret_cast<uint32_t*>(desc->fK ey.get()),
261 newKeyLength); 277 newKeyLength);
262 desc->fInitialized = true; 278 desc->fInitialized = true;
263 } 279 }
264 280
265 GrGLProgramDesc& GrGLProgramDesc::operator= (const GrGLProgramDesc& other) { 281 GrGLProgramDesc& GrGLProgramDesc::operator= (const GrGLProgramDesc& other) {
266 fInitialized = other.fInitialized; 282 fInitialized = other.fInitialized;
267 if (fInitialized) { 283 if (fInitialized) {
268 size_t keyLength = other.keyLength(); 284 size_t keyLength = other.keyLength();
269 fKey.reset(keyLength); 285 fKey.reset(keyLength);
270 memcpy(fKey.get(), other.fKey.get(), keyLength); 286 memcpy(fKey.get(), other.fKey.get(), keyLength);
271 } 287 }
272 return *this; 288 return *this;
273 } 289 }
OLDNEW
« no previous file with comments | « src/gpu/gl/GrGLProgramDesc.h ('k') | src/gpu/gl/GrGLSL.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698