blob: 0189932cacf74e3f3c5842b040d730302206a922 [file] [log] [blame]
joshualitt30ba4362014-08-21 20:18:45 -07001/*
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"
joshualitt47bb3822014-10-07 16:43:25 -07009#include "GrGLProgramBuilder.h"
jvanverthcba99b82015-06-24 06:59:57 -070010#include "../GrGLGLSL.h"
jvanverth39edf762014-12-22 11:44:19 -080011#include "../GrGLGpu.h"
joshualitt30ba4362014-08-21 20:18:45 -070012
joshualitt47bb3822014-10-07 16:43:25 -070013#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)
joshualitt30ba4362014-08-21 20:18:45 -070015
joshualitt47bb3822014-10-07 16:43:25 -070016GrGLVertexBuilder::GrGLVertexBuilder(GrGLProgramBuilder* program)
joshualittdb0d3ca2014-10-07 12:42:26 -070017 : INHERITED(program)
halcanary96fcdcc2015-08-27 07:41:13 -070018 , fRtAdjustName(nullptr) {
joshualittdb0d3ca2014-10-07 12:42:26 -070019}
20
joshualitt74077b92014-10-24 11:26:03 -070021void GrGLVertexBuilder::addVarying(const char* name, GrGLVarying* v) {
joshualitt30ba4362014-08-21 20:18:45 -070022 fOutputs.push_back();
joshualitt74077b92014-10-24 11:26:03 -070023 fOutputs.back().setType(v->fType);
joshualitt30ba4362014-08-21 20:18:45 -070024 fOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier);
25 fProgramBuilder->nameVariable(fOutputs.back().accessName(), 'v', name);
joshualitt74077b92014-10-24 11:26:03 -070026 v->fVsOut = fOutputs.back().getName().c_str();
joshualitt30ba4362014-08-21 20:18:45 -070027}
28
joshualitt47bb3822014-10-07 16:43:25 -070029void GrGLVertexBuilder::emitAttributes(const GrGeometryProcessor& gp) {
joshualitt71c92602015-01-14 08:12:47 -080030 int vaCount = gp.numAttribs();
joshualitt2dd1ae02014-12-03 06:24:10 -080031 for (int i = 0; i < vaCount; i++) {
joshualitt71c92602015-01-14 08:12:47 -080032 this->addAttribute(&gp.getAttrib(i));
joshualitt47bb3822014-10-07 16:43:25 -070033 }
joshualitt2dd1ae02014-12-03 06:24:10 -080034 return;
joshualitt47bb3822014-10-07 16:43:25 -070035}
36
robertphillips46d36f02015-01-18 08:14:14 -080037void GrGLVertexBuilder::transformToNormalizedDeviceSpace(const GrShaderVar& posVar) {
joshualittabb52a12015-01-13 15:02:10 -080038 SkASSERT(!fRtAdjustName);
39
joel.liangd18bb232015-06-04 06:52:29 -070040 GrSLPrecision precision = kDefault_GrSLPrecision;
41 if (fProgramBuilder->ctxInfo().vendor() == kARM_GrGLVendor) {
42 precision = kHigh_GrSLPrecision;
43 }
44
joshualitt4973d9d2014-11-08 09:24:25 -080045 // setup RT Uniform
joshualitt47bb3822014-10-07 16:43:25 -070046 fProgramBuilder->fUniformHandles.fRTAdjustmentUni =
47 fProgramBuilder->addUniform(GrGLProgramBuilder::kVertex_Visibility,
joel.liangd18bb232015-06-04 06:52:29 -070048 kVec4f_GrSLType, precision,
joshualitt4973d9d2014-11-08 09:24:25 -080049 fProgramBuilder->rtAdjustment(),
50 &fRtAdjustName);
bsalomond79c5492015-04-27 10:07:04 -070051 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()) {
robertphillips7f14c9b2015-01-30 14:44:22 -080063 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());
robertphillips46d36f02015-01-18 08:14:14 -080066 } else {
67 SkASSERT(kVec2f_GrSLType == posVar.getType());
robertphillips7f14c9b2015-01-30 14:44:22 -080068 this->codeAppendf("gl_Position = vec4(%s.x * %s.x + %s.y, %s.y * %s.z + %s.w, 0, 1);",
robertphillips46d36f02015-01-18 08:14:14 -080069 posVar.c_str(), fRtAdjustName, fRtAdjustName,
70 posVar.c_str(), fRtAdjustName, fRtAdjustName);
71 }
bsalomond79c5492015-04-27 10:07:04 -070072 // 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
joshualittabb52a12015-01-13 15:02:10 -080074 this->codeAppend("gl_PointSize = 1.0;");
joshualitt47bb3822014-10-07 16:43:25 -070075}
76
77void GrGLVertexBuilder::bindVertexAttributes(GrGLuint programID) {
joshualitt873ad0e2015-01-20 09:08:51 -080078 const GrPrimitiveProcessor& primProc = fProgramBuilder->primitiveProcessor();
joshualitt30ba4362014-08-21 20:18:45 -070079
joshualitt873ad0e2015-01-20 09:08:51 -080080 int vaCount = primProc.numAttribs();
joshualitt2dd1ae02014-12-03 06:24:10 -080081 for (int i = 0; i < vaCount; i++) {
joshualitt873ad0e2015-01-20 09:08:51 -080082 GL_CALL(BindAttribLocation(programID, i, primProc.getAttrib(i).fName));
joshualitt30ba4362014-08-21 20:18:45 -070083 }
joshualitt2dd1ae02014-12-03 06:24:10 -080084 return;
joshualitt30ba4362014-08-21 20:18:45 -070085}
86
joshualitt43466a12015-02-13 17:18:27 -080087bool
88GrGLVertexBuilder::compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) {
jvanverthcba99b82015-06-24 06:59:57 -070089 this->versionDecl() = GrGLGetGLSLVersionDecl(fProgramBuilder->ctxInfo());
cdaltone4017d82015-05-06 11:48:56 -070090 this->compileAndAppendLayoutQualifiers();
joshualitt43466a12015-02-13 17:18:27 -080091 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);
joshualitt30ba4362014-08-21 20:18:45 -070095}
96
joshualitt47bb3822014-10-07 16:43:25 -070097bool 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 }
joshualitt30ba4362014-08-21 20:18:45 -0700105 }
joshualitt47bb3822014-10-07 16:43:25 -0700106 fInputs.push_back(var);
107 return true;
joshualitt30ba4362014-08-21 20:18:45 -0700108}