joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2014 Google Inc. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. |
| 6 | */ |
| 7 | |
| 8 | #include "GrGLVertexShaderBuilder.h" |
joshualitt | 47bb382 | 2014-10-07 16:43:25 -0700 | [diff] [blame] | 9 | #include "GrGLProgramBuilder.h" |
jvanverth | cba99b8 | 2015-06-24 06:59:57 -0700 | [diff] [blame] | 10 | #include "../GrGLGLSL.h" |
jvanverth | 39edf76 | 2014-12-22 11:44:19 -0800 | [diff] [blame] | 11 | #include "../GrGLGpu.h" |
joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 12 | |
joshualitt | 47bb382 | 2014-10-07 16:43:25 -0700 | [diff] [blame] | 13 | #define GL_CALL(X) GR_GL_CALL(fProgramBuilder->gpu()->glInterface(), X) |
| 14 | #define GL_CALL_RET(R, X) GR_GL_CALL_RET(fProgramBuilder->gpu()->glInterface(), R, X) |
joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 15 | |
joshualitt | 47bb382 | 2014-10-07 16:43:25 -0700 | [diff] [blame] | 16 | GrGLVertexBuilder::GrGLVertexBuilder(GrGLProgramBuilder* program) |
joshualitt | db0d3ca | 2014-10-07 12:42:26 -0700 | [diff] [blame] | 17 | : INHERITED(program) |
halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame^] | 18 | , fRtAdjustName(nullptr) { |
joshualitt | db0d3ca | 2014-10-07 12:42:26 -0700 | [diff] [blame] | 19 | } |
| 20 | |
joshualitt | 74077b9 | 2014-10-24 11:26:03 -0700 | [diff] [blame] | 21 | void GrGLVertexBuilder::addVarying(const char* name, GrGLVarying* v) { |
joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 22 | fOutputs.push_back(); |
joshualitt | 74077b9 | 2014-10-24 11:26:03 -0700 | [diff] [blame] | 23 | fOutputs.back().setType(v->fType); |
joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 24 | fOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier); |
| 25 | fProgramBuilder->nameVariable(fOutputs.back().accessName(), 'v', name); |
joshualitt | 74077b9 | 2014-10-24 11:26:03 -0700 | [diff] [blame] | 26 | v->fVsOut = fOutputs.back().getName().c_str(); |
joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 27 | } |
| 28 | |
joshualitt | 47bb382 | 2014-10-07 16:43:25 -0700 | [diff] [blame] | 29 | void GrGLVertexBuilder::emitAttributes(const GrGeometryProcessor& gp) { |
joshualitt | 71c9260 | 2015-01-14 08:12:47 -0800 | [diff] [blame] | 30 | int vaCount = gp.numAttribs(); |
joshualitt | 2dd1ae0 | 2014-12-03 06:24:10 -0800 | [diff] [blame] | 31 | for (int i = 0; i < vaCount; i++) { |
joshualitt | 71c9260 | 2015-01-14 08:12:47 -0800 | [diff] [blame] | 32 | this->addAttribute(&gp.getAttrib(i)); |
joshualitt | 47bb382 | 2014-10-07 16:43:25 -0700 | [diff] [blame] | 33 | } |
joshualitt | 2dd1ae0 | 2014-12-03 06:24:10 -0800 | [diff] [blame] | 34 | return; |
joshualitt | 47bb382 | 2014-10-07 16:43:25 -0700 | [diff] [blame] | 35 | } |
| 36 | |
robertphillips | 46d36f0 | 2015-01-18 08:14:14 -0800 | [diff] [blame] | 37 | void GrGLVertexBuilder::transformToNormalizedDeviceSpace(const GrShaderVar& posVar) { |
joshualitt | abb52a1 | 2015-01-13 15:02:10 -0800 | [diff] [blame] | 38 | SkASSERT(!fRtAdjustName); |
| 39 | |
joel.liang | d18bb23 | 2015-06-04 06:52:29 -0700 | [diff] [blame] | 40 | GrSLPrecision precision = kDefault_GrSLPrecision; |
| 41 | if (fProgramBuilder->ctxInfo().vendor() == kARM_GrGLVendor) { |
| 42 | precision = kHigh_GrSLPrecision; |
| 43 | } |
| 44 | |
joshualitt | 4973d9d | 2014-11-08 09:24:25 -0800 | [diff] [blame] | 45 | // setup RT Uniform |
joshualitt | 47bb382 | 2014-10-07 16:43:25 -0700 | [diff] [blame] | 46 | fProgramBuilder->fUniformHandles.fRTAdjustmentUni = |
| 47 | fProgramBuilder->addUniform(GrGLProgramBuilder::kVertex_Visibility, |
joel.liang | d18bb23 | 2015-06-04 06:52:29 -0700 | [diff] [blame] | 48 | kVec4f_GrSLType, precision, |
joshualitt | 4973d9d | 2014-11-08 09:24:25 -0800 | [diff] [blame] | 49 | fProgramBuilder->rtAdjustment(), |
| 50 | &fRtAdjustName); |
bsalomon | d79c549 | 2015-04-27 10:07:04 -0700 | [diff] [blame] | 51 | if (this->getProgramBuilder()->desc().header().fSnapVerticesToPixelCenters) { |
| 52 | if (kVec3f_GrSLType == posVar.getType()) { |
| 53 | const char* p = posVar.c_str(); |
| 54 | this->codeAppendf("{vec2 _posTmp = vec2(%s.x/%s.z, %s.y/%s.z);", p, p, p, p); |
| 55 | } else { |
| 56 | SkASSERT(kVec2f_GrSLType == posVar.getType()); |
| 57 | this->codeAppendf("{vec2 _posTmp = %s;", posVar.c_str()); |
| 58 | } |
| 59 | this->codeAppendf("_posTmp = floor(_posTmp) + vec2(0.5, 0.5);" |
| 60 | "gl_Position = vec4(_posTmp.x * %s.x + %s.y, _posTmp.y * %s.z + %s.w, 0, 1);}", |
| 61 | fRtAdjustName, fRtAdjustName, fRtAdjustName, fRtAdjustName); |
| 62 | } else if (kVec3f_GrSLType == posVar.getType()) { |
robertphillips | 7f14c9b | 2015-01-30 14:44:22 -0800 | [diff] [blame] | 63 | this->codeAppendf("gl_Position = vec4(dot(%s.xz, %s.xy)/%s.z, dot(%s.yz, %s.zw)/%s.z, 0, 1);", |
| 64 | posVar.c_str(), fRtAdjustName, posVar.c_str(), |
| 65 | posVar.c_str(), fRtAdjustName, posVar.c_str()); |
robertphillips | 46d36f0 | 2015-01-18 08:14:14 -0800 | [diff] [blame] | 66 | } else { |
| 67 | SkASSERT(kVec2f_GrSLType == posVar.getType()); |
robertphillips | 7f14c9b | 2015-01-30 14:44:22 -0800 | [diff] [blame] | 68 | this->codeAppendf("gl_Position = vec4(%s.x * %s.x + %s.y, %s.y * %s.z + %s.w, 0, 1);", |
robertphillips | 46d36f0 | 2015-01-18 08:14:14 -0800 | [diff] [blame] | 69 | posVar.c_str(), fRtAdjustName, fRtAdjustName, |
| 70 | posVar.c_str(), fRtAdjustName, fRtAdjustName); |
| 71 | } |
bsalomon | d79c549 | 2015-04-27 10:07:04 -0700 | [diff] [blame] | 72 | // We could have the GrGeometryProcessor do this, but its just easier to have it performed |
| 73 | // here. If we ever need to set variable pointsize, then we can reinvestigate |
joshualitt | abb52a1 | 2015-01-13 15:02:10 -0800 | [diff] [blame] | 74 | this->codeAppend("gl_PointSize = 1.0;"); |
joshualitt | 47bb382 | 2014-10-07 16:43:25 -0700 | [diff] [blame] | 75 | } |
| 76 | |
| 77 | void GrGLVertexBuilder::bindVertexAttributes(GrGLuint programID) { |
joshualitt | 873ad0e | 2015-01-20 09:08:51 -0800 | [diff] [blame] | 78 | const GrPrimitiveProcessor& primProc = fProgramBuilder->primitiveProcessor(); |
joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 79 | |
joshualitt | 873ad0e | 2015-01-20 09:08:51 -0800 | [diff] [blame] | 80 | int vaCount = primProc.numAttribs(); |
joshualitt | 2dd1ae0 | 2014-12-03 06:24:10 -0800 | [diff] [blame] | 81 | for (int i = 0; i < vaCount; i++) { |
joshualitt | 873ad0e | 2015-01-20 09:08:51 -0800 | [diff] [blame] | 82 | GL_CALL(BindAttribLocation(programID, i, primProc.getAttrib(i).fName)); |
joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 83 | } |
joshualitt | 2dd1ae0 | 2014-12-03 06:24:10 -0800 | [diff] [blame] | 84 | return; |
joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 85 | } |
| 86 | |
joshualitt | 43466a1 | 2015-02-13 17:18:27 -0800 | [diff] [blame] | 87 | bool |
| 88 | GrGLVertexBuilder::compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) { |
jvanverth | cba99b8 | 2015-06-24 06:59:57 -0700 | [diff] [blame] | 89 | this->versionDecl() = GrGLGetGLSLVersionDecl(fProgramBuilder->ctxInfo()); |
cdalton | e4017d8 | 2015-05-06 11:48:56 -0700 | [diff] [blame] | 90 | this->compileAndAppendLayoutQualifiers(); |
joshualitt | 43466a1 | 2015-02-13 17:18:27 -0800 | [diff] [blame] | 91 | fProgramBuilder->appendUniformDecls(GrGLProgramBuilder::kVertex_Visibility, &this->uniforms()); |
| 92 | this->appendDecls(fInputs, &this->inputs()); |
| 93 | this->appendDecls(fOutputs, &this->outputs()); |
| 94 | return this->finalize(programId, GR_GL_VERTEX_SHADER, shaderIds); |
joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 95 | } |
| 96 | |
joshualitt | 47bb382 | 2014-10-07 16:43:25 -0700 | [diff] [blame] | 97 | bool GrGLVertexBuilder::addAttribute(const GrShaderVar& var) { |
| 98 | SkASSERT(GrShaderVar::kAttribute_TypeModifier == var.getTypeModifier()); |
| 99 | for (int i = 0; i < fInputs.count(); ++i) { |
| 100 | const GrGLShaderVar& attr = fInputs[i]; |
| 101 | // if attribute already added, don't add it again |
| 102 | if (attr.getName().equals(var.getName())) { |
| 103 | return false; |
| 104 | } |
joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 105 | } |
joshualitt | 47bb382 | 2014-10-07 16:43:25 -0700 | [diff] [blame] | 106 | fInputs.push_back(var); |
| 107 | return true; |
joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 108 | } |