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

Side by Side Diff: src/gpu/gl/builders/GrGLProgramBuilder.cpp

Issue 678953002: Default geometry processor (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix dm bug Created 6 years, 1 month 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
OLDNEW
1 /* 1 /*
2 * Copyright 2014 Google Inc. 2 * Copyright 2014 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 "GrGLProgramBuilder.h" 8 #include "GrGLProgramBuilder.h"
9 #include "gl/GrGLProgram.h" 9 #include "gl/GrGLProgram.h"
10 #include "gl/GrGLSLPrettyPrint.h" 10 #include "gl/GrGLSLPrettyPrint.h"
(...skipping 19 matching lines...) Expand all
30 30
31 GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState, 31 GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState,
32 const GrGLProgramDesc& desc, 32 const GrGLProgramDesc& desc,
33 GrGpu::DrawType drawType, 33 GrGpu::DrawType drawType,
34 GrGpuGL* gpu) { 34 GrGpuGL* gpu) {
35 // create a builder. This will be handed off to effects so they can use it to add 35 // create a builder. This will be handed off to effects so they can use it to add
36 // uniforms, varyings, textures, etc 36 // uniforms, varyings, textures, etc
37 SkAutoTDelete<GrGLProgramBuilder> builder(CreateProgramBuilder(desc, 37 SkAutoTDelete<GrGLProgramBuilder> builder(CreateProgramBuilder(desc,
38 optState, 38 optState,
39 drawType, 39 drawType,
40 optState.hasG eometryProcessor(),
41 gpu)); 40 gpu));
42 41 return builder->create();
43 GrGLProgramBuilder* pb = builder.get();
44 const GrGLProgramDesc::KeyHeader& header = pb->header();
45
46 // emit code to read the dst copy texture, if necessary
47 if (GrGLFragmentShaderBuilder::kNoDstRead_DstReadKey != header.fDstReadKey
48 && !gpu->glCaps().fbFetchSupport()) {
49 pb->fFS.emitCodeToReadDstTexture();
50 }
51
52 // get the initial color and coverage to feed into the first effect in each effect chain
53 GrGLSLExpr4 inputColor, inputCoverage;
54 pb->setupUniformColorAndCoverageIfNeeded(&inputColor, &inputCoverage);
55
56 // if we have a vertex shader(we don't only if we are using NVPR or NVPR ES) , then we may have
57 // to setup a few more things like builtin vertex attributes
58 bool hasVertexShader = !header.fUseFragShaderOnly;
59 if (hasVertexShader) {
60 pb->fVS.setupLocalCoords();
61 pb->fVS.transformGLToSkiaCoords();
62 if (header.fEmitsPointSize) {
63 pb->fVS.codeAppend("gl_PointSize = 1.0;");
64 }
65 if (GrGLProgramDesc::kAttribute_ColorInput == header.fColorInput) {
66 pb->fVS.setupBuiltinVertexAttribute("Color", &inputColor);
67 }
68 if (GrGLProgramDesc::kAttribute_ColorInput == header.fCoverageInput) {
69 pb->fVS.setupBuiltinVertexAttribute("Coverage", &inputCoverage);
70 }
71 }
72
73 pb->emitAndInstallProcs(optState, &inputColor, &inputCoverage);
74
75 if (hasVertexShader) {
76 pb->fVS.transformSkiaToGLCoords();
77 }
78
79 // write the secondary color output if necessary
80 if (GrOptDrawState::kNone_SecondaryOutputType != header.fSecondaryOutputType ) {
81 pb->fFS.enableSecondaryOutput(inputColor, inputCoverage);
82 }
83
84 pb->fFS.combineColorAndCoverage(inputColor, inputCoverage);
85
86 return pb->finalize();
87 } 42 }
88 43
89 GrGLProgramBuilder* 44 GrGLProgramBuilder*
90 GrGLProgramBuilder::CreateProgramBuilder(const GrGLProgramDesc& desc, 45 GrGLProgramBuilder::CreateProgramBuilder(const GrGLProgramDesc& desc,
91 const GrOptDrawState& optState, 46 const GrOptDrawState& optState,
92 GrGpu::DrawType drawType, 47 GrGpu::DrawType drawType,
93 bool hasGeometryProcessor,
94 GrGpuGL* gpu) { 48 GrGpuGL* gpu) {
49 // We always have a GP but it gets ignored for nvpr
95 if (desc.getHeader().fUseFragShaderOnly) { 50 if (desc.getHeader().fUseFragShaderOnly) {
96 SkASSERT(gpu->glCaps().pathRenderingSupport()); 51 SkASSERT(gpu->glCaps().pathRenderingSupport());
97 SkASSERT(gpu->glPathRendering()->texturingMode() == 52 SkASSERT(gpu->glPathRendering()->texturingMode() ==
98 GrGLPathRendering::FixedFunction_TexturingMode); 53 GrGLPathRendering::FixedFunction_TexturingMode);
99 SkASSERT(!hasGeometryProcessor);
100 return SkNEW_ARGS(GrGLLegacyNvprProgramBuilder, (gpu, optState, desc)); 54 return SkNEW_ARGS(GrGLLegacyNvprProgramBuilder, (gpu, optState, desc));
101 } else if (GrGpu::IsPathRenderingDrawType(drawType)) { 55 } else if (GrGpu::IsPathRenderingDrawType(drawType)) {
102 SkASSERT(gpu->glCaps().pathRenderingSupport()); 56 SkASSERT(gpu->glCaps().pathRenderingSupport());
103 SkASSERT(gpu->glPathRendering()->texturingMode() == 57 SkASSERT(gpu->glPathRendering()->texturingMode() ==
104 GrGLPathRendering::SeparableShaders_TexturingMode); 58 GrGLPathRendering::SeparableShaders_TexturingMode);
105 SkASSERT(!hasGeometryProcessor);
106 return SkNEW_ARGS(GrGLNvprProgramBuilder, (gpu, optState, desc)); 59 return SkNEW_ARGS(GrGLNvprProgramBuilder, (gpu, optState, desc));
107 } else { 60 } else {
108 return SkNEW_ARGS(GrGLProgramBuilder, (gpu, optState, desc)); 61 return SkNEW_ARGS(GrGLProgramBuilder, (gpu, optState, desc));
109 } 62 }
110 } 63 }
111 64
112 ///////////////////////////////////////////////////////////////////////////// 65 /////////////////////////////////////////////////////////////////////////////
113 66
114 GrGLProgramBuilder::GrGLProgramBuilder(GrGpuGL* gpu, 67 GrGLProgramBuilder::GrGLProgramBuilder(GrGpuGL* gpu,
115 const GrOptDrawState& optState, 68 const GrOptDrawState& optState,
116 const GrGLProgramDesc& desc) 69 const GrGLProgramDesc& desc)
117 : fVS(this) 70 : fVS(this)
118 , fGS(this) 71 , fGS(this)
119 , fFS(this, desc) 72 , fFS(this, desc)
120 , fOutOfStage(true) 73 , fOutOfStage(true)
121 , fStageIndex(-1) 74 , fStageIndex(-1)
122 , fGeometryProcessor(NULL) 75 , fGeometryProcessor(NULL)
123 , fOptState(optState) 76 , fOptState(optState)
124 , fDesc(desc) 77 , fDesc(desc)
125 , fGpu(gpu) 78 , fGpu(gpu)
126 , fUniforms(kVarsPerBlock) { 79 , fUniforms(kVarsPerBlock) {
127 } 80 }
128 81
82 GrGLProgram* GrGLProgramBuilder::create() {
83 const GrGLProgramDesc::KeyHeader& header = this->header();
84
85 // emit code to read the dst copy texture, if necessary
86 if (GrGLFragmentShaderBuilder::kNoDstRead_DstReadKey != header.fDstReadKey
87 && !fGpu->glCaps().fbFetchSupport()) {
88 this->fFS.emitCodeToReadDstTexture();
89 }
90
91 // get the initial color and coverage to feed into the first effect in each effect chain
92 GrGLSLExpr4 inputColor, inputCoverage;
93 this->setupUniformColorAndCoverageIfNeeded(&inputColor, &inputCoverage);
94
95 // We always have a vertex shader in our default program
96 fVS.setupLocalCoords();
97
98 // Setup default view matrix
99 this->fUniformHandles.fViewMatrixUni =
100 this->addUniform(GrGLProgramBuilder::kVertex_Visibility,
101 kMat33f_GrSLType,
102 fOptState.getGeometryProcessor()->uViewM());
103 if (header.fEmitsPointSize) {
104 this->fVS.codeAppend("gl_PointSize = 1.0;");
105 }
106 if (GrGLProgramDesc::kAttribute_ColorInput == header.fColorInput) {
107 this->fVS.setupBuiltinVertexAttribute("Color", &inputColor);
108 }
109 if (GrGLProgramDesc::kAttribute_ColorInput == header.fCoverageInput) {
110 this->fVS.setupBuiltinVertexAttribute("Coverage", &inputCoverage);
111 }
112
113 this->emitAndInstallProcs(&inputColor, &inputCoverage);
114
115 // write the secondary color output if necessary
116 if (GrOptDrawState::kNone_SecondaryOutputType != header.fSecondaryOutputType ) {
117 fFS.enableSecondaryOutput(inputColor, inputCoverage);
118 }
119
120 fFS.combineColorAndCoverage(inputColor, inputCoverage);
121
122 return this->finalize();
123 }
124
129 void GrGLProgramBuilder::addVarying(const char* name, 125 void GrGLProgramBuilder::addVarying(const char* name,
130 GrGLVarying* varying, 126 GrGLVarying* varying,
131 GrGLShaderVar::Precision fsPrecision) { 127 GrGLShaderVar::Precision fsPrecision) {
132 SkASSERT(varying); 128 SkASSERT(varying);
133 if (varying->vsVarying()) { 129 if (varying->vsVarying()) {
134 fVS.addVarying(name, varying); 130 fVS.addVarying(name, varying);
135 } 131 }
136 if (fOptState.hasGeometryProcessor() && fOptState.getGeometryProcessor()->wi llUseGeoShader()) { 132 if (fOptState.hasGeometryProcessor() && fOptState.getGeometryProcessor()->wi llUseGeoShader()) {
137 fGS.addVarying(name, varying); 133 fGS.addVarying(name, varying);
138 } 134 }
(...skipping 23 matching lines...) Expand all
162 int co unt, 158 int co unt,
163 const char** outName) { 159 const char** outName) {
164 SkASSERT(name && strlen(name)); 160 SkASSERT(name && strlen(name));
165 SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_Visibility | kFr agment_Visibility); 161 SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_Visibility | kFr agment_Visibility);
166 SkASSERT(0 == (~kVisibilityMask & visibility)); 162 SkASSERT(0 == (~kVisibilityMask & visibility));
167 SkASSERT(0 != visibility); 163 SkASSERT(0 != visibility);
168 164
169 UniformInfo& uni = fUniforms.push_back(); 165 UniformInfo& uni = fUniforms.push_back();
170 uni.fVariable.setType(type); 166 uni.fVariable.setType(type);
171 uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); 167 uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
172 this->nameVariable(uni.fVariable.accessName(), 'u', name); 168 // TODO this is a bit hacky, lets think of a better way. Basically we need to be able to use
169 // the uniform view matrix name in the GP, and the GP is immutable so it has to tell the PB
170 // exactly what name it wants to use for the uniform view matrix. If we pre fix anythings, then
171 // the names will mismatch. I think the correct solution is to have all GPs which need the
172 // uniform view matrix, they should upload the view matrix in their setData along with regular
173 // uniforms.
174 char prefix = 'u';
175 if ('u' == name[0]) {
176 prefix = '\0';
177 }
178 this->nameVariable(uni.fVariable.accessName(), prefix, name);
173 uni.fVariable.setArrayCount(count); 179 uni.fVariable.setArrayCount(count);
174 uni.fVisibility = visibility; 180 uni.fVisibility = visibility;
175 181
176 // If it is visible in both the VS and FS, the precision must match. 182 // If it is visible in both the VS and FS, the precision must match.
177 // We declare a default FS precision, but not a default VS. So set the var 183 // We declare a default FS precision, but not a default VS. So set the var
178 // to use the default FS precision. 184 // to use the default FS precision.
179 if ((kVertex_Visibility | kFragment_Visibility) == visibility) { 185 if ((kVertex_Visibility | kFragment_Visibility) == visibility) {
180 // the fragment and vertex precisions must match 186 // the fragment and vertex precisions must match
181 uni.fVariable.setPrecision(kDefaultFragmentPrecision); 187 uni.fVariable.setPrecision(kDefaultFragmentPrecision);
182 } 188 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 this->addUniform(GrGLProgramBuilder::kFragment_Visibility, 227 this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
222 kVec4f_GrSLType, 228 kVec4f_GrSLType,
223 "Coverage", 229 "Coverage",
224 &name); 230 &name);
225 *inputCoverage = GrGLSLExpr4(name); 231 *inputCoverage = GrGLSLExpr4(name);
226 } else if (GrGLProgramDesc::kAllOnes_ColorInput == header.fCoverageInput) { 232 } else if (GrGLProgramDesc::kAllOnes_ColorInput == header.fCoverageInput) {
227 *inputCoverage = GrGLSLExpr4(1); 233 *inputCoverage = GrGLSLExpr4(1);
228 } 234 }
229 } 235 }
230 236
231 void GrGLProgramBuilder::emitAndInstallProcs(const GrOptDrawState& optState, 237 void GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr 4* inputCoverage) {
232 GrGLSLExpr4* inputColor, 238 // We need to collect all of the transforms to thread them through the GP in the case of GPs
233 GrGLSLExpr4* inputCoverage) { 239 // which use additional shader stages between the VS and the FS. To do this we emit a dummy
240 // input coverage
241 AutoStageAdvance adv(this);
242 SkString outColorName;
243 this->nameVariable(&outColorName, '\0', "gpOutput");
244 GrGLSLExpr4 coverageInput = outColorName;
245 GrGLSLExpr4 gpOutput = coverageInput;
246
247 // Emit fragment processors
234 fFragmentProcessors.reset(SkNEW(GrGLInstalledFragProcs)); 248 fFragmentProcessors.reset(SkNEW(GrGLInstalledFragProcs));
235 int numProcs = optState.numFragmentStages(); 249 int numProcs = fOptState.numFragmentStages();
236 this->emitAndInstallFragProcs(0, optState.numColorStages(), inputColor); 250 this->emitAndInstallFragProcs(0, fOptState.numColorStages(), inputColor);
237 if (optState.hasGeometryProcessor()) { 251 this->emitAndInstallFragProcs(fOptState.numColorStages(), numProcs, &covera geInput);
238 const GrGeometryProcessor& gp = *optState.getGeometryProcessor(); 252
239 fVS.emitAttributes(gp); 253 // We have to save the existing code stack, and then append it to the fragme nt shader code
240 ProcKeyProvider keyProvider(&fDesc, ProcKeyProvider::kGeometry_Processor Type); 254 // after emiting the GP
241 GrGLSLExpr4 output; 255 SkString existingCode(fFS.fCode);
242 this->emitAndInstallProc<GrGeometryProcessor>(gp, 0, keyProvider, *input Coverage, &output); 256 fFS.fCode.reset();
243 *inputCoverage = output; 257 const GrGeometryProcessor& gp = *fOptState.getGeometryProcessor();
244 } 258 fVS.emitAttributes(gp);
245 this->emitAndInstallFragProcs(optState.numColorStages(), numProcs, inputCov erage); 259 ProcKeyProvider keyProvider(&fDesc, ProcKeyProvider::kGeometry_ProcessorType );
260 this->emitAndInstallProc<GrGeometryProcessor>(gp, 0, keyProvider, *inputCove rage, &gpOutput);
261 fFS.fCode.append(existingCode);
262 *inputCoverage = coverageInput;
246 } 263 }
247 264
248 void GrGLProgramBuilder::emitAndInstallFragProcs(int procOffset, int numProcs, G rGLSLExpr4* inOut) { 265 void GrGLProgramBuilder::emitAndInstallFragProcs(int procOffset, int numProcs, G rGLSLExpr4* inOut) {
249 ProcKeyProvider keyProvider(&fDesc, ProcKeyProvider::kFragment_ProcessorType ); 266 ProcKeyProvider keyProvider(&fDesc, ProcKeyProvider::kFragment_ProcessorType );
250 for (int e = procOffset; e < numProcs; ++e) { 267 for (int e = procOffset; e < numProcs; ++e) {
251 GrGLSLExpr4 output; 268 GrGLSLExpr4 output;
252 const GrFragmentStage& stage = fOptState.getFragmentStage(e); 269 const GrFragmentStage& stage = fOptState.getFragmentStage(e);
253 this->emitAndInstallProc<GrFragmentStage>(stage, e, keyProvider, *inOut, &output); 270 this->emitAndInstallProc<GrFragmentStage>(stage, e, keyProvider, *inOut, &output);
254 *inOut = output; 271 *inOut = output;
255 } 272 }
256 } 273 }
257 274
258 // TODO Processors cannot output zeros because an empty string is all 1s 275 // TODO Processors cannot output zeros because an empty string is all 1s
259 // the fix is to allow effects to take the GrGLSLExpr4 directly 276 // the fix is to allow effects to take the GrGLSLExpr4 directly
260 template <class Proc> 277 template <class Proc>
261 void GrGLProgramBuilder::emitAndInstallProc(const Proc& proc, 278 void GrGLProgramBuilder::emitAndInstallProc(const Proc& proc,
262 int index, 279 int index,
263 const ProcKeyProvider keyProvider, 280 const ProcKeyProvider keyProvider,
264 const GrGLSLExpr4& input, 281 const GrGLSLExpr4& input,
265 GrGLSLExpr4* output) { 282 GrGLSLExpr4* output) {
266 // Program builders have a bit of state we need to clear with each effect 283 // Program builders have a bit of state we need to clear with each effect
267 AutoStageAdvance adv(this); 284 AutoStageAdvance adv(this);
268 285
269 // create var to hold stage result 286 // create var to hold stage result. If we already have a valid output name, just use that
287 // otherwise create a new mangled one.
270 SkString outColorName; 288 SkString outColorName;
271 this->nameVariable(&outColorName, '\0', "output"); 289 if (output->isValid()) {
290 outColorName = output->c_str();
291 } else {
292 this->nameVariable(&outColorName, '\0', "output");
293 }
272 fFS.codeAppendf("vec4 %s;", outColorName.c_str()); 294 fFS.codeAppendf("vec4 %s;", outColorName.c_str());
273 *output = outColorName; 295 *output = outColorName;
274 296
275 // Enclose custom code in a block to avoid namespace conflicts 297 // Enclose custom code in a block to avoid namespace conflicts
276 SkString openBrace; 298 SkString openBrace;
277 openBrace.printf("{ // Stage %d\n", fStageIndex); 299 openBrace.printf("{ // Stage %d\n", fStageIndex);
278 fFS.codeAppend(openBrace.c_str()); 300 fFS.codeAppend(openBrace.c_str());
279 301
280 this->emitAndInstallProc(proc, keyProvider.get(index), output->c_str(), 302 this->emitAndInstallProc(proc, keyProvider.get(index), output->c_str(),
281 input.isOnes() ? NULL : input.c_str()); 303 input.isOnes() ? NULL : input.c_str());
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 uniName, 383 uniName,
362 &uniName).toShaderBuilder Index(); 384 &uniName).toShaderBuilder Index();
363 385
364 const char* varyingName = "MatrixCoord"; 386 const char* varyingName = "MatrixCoord";
365 SkString suffixedVaryingName; 387 SkString suffixedVaryingName;
366 if (0 != t) { 388 if (0 != t) {
367 suffixedVaryingName.append(varyingName); 389 suffixedVaryingName.append(varyingName);
368 suffixedVaryingName.appendf("_%i", t); 390 suffixedVaryingName.appendf("_%i", t);
369 varyingName = suffixedVaryingName.c_str(); 391 varyingName = suffixedVaryingName.c_str();
370 } 392 }
393 const char* coords = kPosition_GrCoordSet == effect->coordTransform(t).s ourceCoords() ?
394 fVS.positionAttribute().c_s tr() :
395 fVS.localCoordsAttribute(). c_str();
371 GrGLVertToFrag v(varyingType); 396 GrGLVertToFrag v(varyingType);
372 this->addVarying(varyingName, &v); 397 this->addCoordVarying(varyingName, &v, uniName, coords);
373 398
374 const GrGLShaderVar& coords =
375 kPosition_GrCoordSet == effect->coordTransform(t).sourceCoords() ?
376 fVS.positionAttribute() :
377 fVS.localCoordsAttribute();
378
379 // varying = matrix * coords (logically)
380 SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingTyp e); 399 SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingTyp e);
381 if (kVec2f_GrSLType == varyingType) {
382 fVS.codeAppendf("%s = (%s * vec3(%s, 1)).xy;",
383 v.vsOut(), uniName, coords.c_str());
384 } else {
385 fVS.codeAppendf("%s = %s * vec3(%s, 1);",
386 v.vsOut(), uniName, coords.c_str());
387 }
388 SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords, 400 SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords,
389 (SkString(v.fsIn()), varyingType)); 401 (SkString(v.fsIn()), varyingType));
390 } 402 }
391 } 403 }
392 404
393 void GrGLProgramBuilder::emitSamplers(const GrProcessor& processor, 405 void GrGLProgramBuilder::emitSamplers(const GrProcessor& processor,
394 GrGLProcessor::TextureSamplerArray* outSam plers, 406 GrGLProcessor::TextureSamplerArray* outSam plers,
395 GrGLInstalledProc* ip) { 407 GrGLInstalledProc* ip) {
396 int numTextures = processor.numTextures(); 408 int numTextures = processor.numTextures();
397 ip->fSamplers.push_back_n(numTextures); 409 ip->fSamplers.push_back_n(numTextures);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 } 520 }
509 521
510 //////////////////////////////////////////////////////////////////////////////// /////////////////// 522 //////////////////////////////////////////////////////////////////////////////// ///////////////////
511 523
512 GrGLInstalledFragProcs::~GrGLInstalledFragProcs() { 524 GrGLInstalledFragProcs::~GrGLInstalledFragProcs() {
513 int numProcs = fProcs.count(); 525 int numProcs = fProcs.count();
514 for (int e = 0; e < numProcs; ++e) { 526 for (int e = 0; e < numProcs; ++e) {
515 SkDELETE(fProcs[e]); 527 SkDELETE(fProcs[e]);
516 } 528 }
517 } 529 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698