blob: 7ddd8613f19b571f606ac6000682bb4fc1b8c3e9 [file] [log] [blame]
junov@google.comf93e7172011-03-31 21:26:24 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * Copyright 2011 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.
junov@google.comf93e7172011-03-31 21:26:24 +00006 */
7
8#include "GrGLProgram.h"
9
tomhudson@google.comd8f856c2012-05-10 12:13:36 +000010#include "GrAllocator.h"
bsalomon@google.coma469c282012-10-24 18:28:34 +000011#include "GrEffect.h"
bsalomon@google.com77af6802013-10-02 13:04:56 +000012#include "GrCoordTransform.h"
bsalomon@google.comc7818882013-03-20 19:19:53 +000013#include "GrDrawEffect.h"
bsalomon@google.comd698f772012-10-25 13:22:00 +000014#include "GrGLEffect.h"
bsalomon@google.com34cccde2013-01-04 18:34:30 +000015#include "GrGpuGL.h"
bsalomon@google.com4fa66942011-09-20 19:06:12 +000016#include "GrGLShaderVar.h"
bsalomon@google.com018f1792013-04-18 19:36:09 +000017#include "GrGLSL.h"
Scroggo97c88c22011-05-11 14:05:25 +000018#include "SkXfermode.h"
19
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +000020SK_DEFINE_INST_COUNT(GrGLProgram)
21
commit-bot@chromium.org9188a152013-09-05 18:28:24 +000022#define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X)
23#define GL_CALL_RET(R, X) GR_GL_CALL_RET(fGpu->glInterface(), R, X)
bsalomon@google.comecb60aa2012-07-18 13:20:29 +000024
commit-bot@chromium.org9188a152013-09-05 18:28:24 +000025GrGLProgram* GrGLProgram::Create(GrGpuGL* gpu,
bsalomon@google.com31ec7982013-03-27 18:14:57 +000026 const GrGLProgramDesc& desc,
bsalomon@google.com2c84aa32013-06-06 20:28:57 +000027 const GrEffectStage* colorStages[],
28 const GrEffectStage* coverageStages[]) {
commit-bot@chromium.org9188a152013-09-05 18:28:24 +000029 GrGLProgram* program = SkNEW_ARGS(GrGLProgram, (gpu, desc, colorStages, coverageStages));
bsalomon@google.comecb60aa2012-07-18 13:20:29 +000030 if (!program->succeeded()) {
31 delete program;
32 program = NULL;
33 }
34 return program;
35}
36
commit-bot@chromium.org9188a152013-09-05 18:28:24 +000037GrGLProgram::GrGLProgram(GrGpuGL* gpu,
bsalomon@google.com31ec7982013-03-27 18:14:57 +000038 const GrGLProgramDesc& desc,
bsalomon@google.com2c84aa32013-06-06 20:28:57 +000039 const GrEffectStage* colorStages[],
40 const GrEffectStage* coverageStages[])
commit-bot@chromium.org9188a152013-09-05 18:28:24 +000041: fGpu(gpu)
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +000042, fUniformManager(gpu)
43, fHasVertexShader(false)
44, fNumTexCoordSets(0) {
bsalomon@google.comecb60aa2012-07-18 13:20:29 +000045 fDesc = desc;
bsalomon@google.comecb60aa2012-07-18 13:20:29 +000046 fProgramID = 0;
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +000047
bsalomon@google.com804e9942013-06-06 18:04:38 +000048 fDstCopyTexUnit = -1;
49
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +000050 fColor = GrColor_ILLEGAL;
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +000051
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +000052 if (fDesc.getHeader().fHasVertexCode ||
commit-bot@chromium.org8e919ad2013-10-21 14:48:23 +000053 !fGpu->shouldUseFixedFunctionTexturing()) {
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +000054 GrGLFullShaderBuilder fullBuilder(fGpu, fUniformManager, fDesc);
55 if (this->genProgram(&fullBuilder, colorStages, coverageStages)) {
56 fUniformHandles.fViewMatrixUni = fullBuilder.getViewMatrixUniform();
57 fHasVertexShader = true;
58 }
59 } else {
60 GrGLFragmentOnlyShaderBuilder fragmentOnlyBuilder(fGpu, fUniformManager, fDesc);
61 if (this->genProgram(&fragmentOnlyBuilder, colorStages, coverageStages)) {
62 fNumTexCoordSets = fragmentOnlyBuilder.getNumTexCoordSets();
63 }
64 }
junov@google.comf93e7172011-03-31 21:26:24 +000065}
66
67GrGLProgram::~GrGLProgram() {
bsalomon@google.comecb60aa2012-07-18 13:20:29 +000068 if (fProgramID) {
69 GL_CALL(DeleteProgram(fProgramID));
70 }
junov@google.comf93e7172011-03-31 21:26:24 +000071}
72
bsalomon@google.comecb60aa2012-07-18 13:20:29 +000073void GrGLProgram::abandon() {
bsalomon@google.comecb60aa2012-07-18 13:20:29 +000074 fProgramID = 0;
75}
76
tomhudson@google.com0d3f1fb2011-06-01 19:27:31 +000077void GrGLProgram::overrideBlend(GrBlendCoeff* srcCoeff,
bsalomon@google.com271cffc2011-05-20 14:13:56 +000078 GrBlendCoeff* dstCoeff) const {
bsalomon@google.com2db3ded2013-05-22 14:34:04 +000079 switch (fDesc.getHeader().fCoverageOutput) {
bsalomon@google.com5920ac22013-04-19 13:14:45 +000080 case GrGLProgramDesc::kModulate_CoverageOutput:
bsalomon@google.com271cffc2011-05-20 14:13:56 +000081 break;
bsalomon@google.com5920ac22013-04-19 13:14:45 +000082 // The prog will write a coverage value to the secondary
bsalomon@google.com271cffc2011-05-20 14:13:56 +000083 // output and the dst is blended by one minus that value.
bsalomon@google.com5920ac22013-04-19 13:14:45 +000084 case GrGLProgramDesc::kSecondaryCoverage_CoverageOutput:
85 case GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput:
86 case GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput:
87 *dstCoeff = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
88 break;
89 case GrGLProgramDesc::kCombineWithDst_CoverageOutput:
90 // We should only have set this if the blend was specified as (1, 0)
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000091 SkASSERT(kOne_GrBlendCoeff == *srcCoeff && kZero_GrBlendCoeff == *dstCoeff);
bsalomon@google.com5920ac22013-04-19 13:14:45 +000092 break;
bsalomon@google.com271cffc2011-05-20 14:13:56 +000093 default:
bsalomon@google.com5920ac22013-04-19 13:14:45 +000094 GrCrash("Unexpected coverage output");
bsalomon@google.com271cffc2011-05-20 14:13:56 +000095 break;
96 }
97}
98
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +000099bool GrGLProgram::genProgram(GrGLShaderBuilder* builder,
100 const GrEffectStage* colorStages[],
bsalomon@google.com2c84aa32013-06-06 20:28:57 +0000101 const GrEffectStage* coverageStages[]) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000102 SkASSERT(0 == fProgramID);
bsalomon@google.comecb60aa2012-07-18 13:20:29 +0000103
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000104 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
105
bsalomon@google.com91961302011-05-09 18:39:58 +0000106 // incoming color to current stage being processed.
commit-bot@chromium.orga34995e2013-10-23 05:42:03 +0000107 GrGLSLExpr4 inColor = builder->getInputColor();
commit-bot@chromium.orga4acf122013-09-30 15:13:58 +0000108
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000109 fColorEffects.reset(
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000110 builder->createAndEmitEffects(colorStages,
111 fDesc.effectKeys(),
commit-bot@chromium.orga34995e2013-10-23 05:42:03 +0000112 fDesc.numColorEffects(),
commit-bot@chromium.org824c3462013-10-10 06:30:18 +0000113 &inColor));
Scroggo97c88c22011-05-11 14:05:25 +0000114
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000115 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com018f1792013-04-18 19:36:09 +0000116 // compute the partial coverage
commit-bot@chromium.orga34995e2013-10-23 05:42:03 +0000117 GrGLSLExpr4 inCoverage = builder->getInputCoverage();
skia.committer@gmail.comcb6dc752013-04-19 07:01:00 +0000118
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000119 fCoverageEffects.reset(
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000120 builder->createAndEmitEffects(coverageStages,
121 fDesc.getEffectKeys() + fDesc.numColorEffects(),
122 fDesc.numCoverageEffects(),
commit-bot@chromium.org824c3462013-10-10 06:30:18 +0000123 &inCoverage));
bsalomon@google.com504976e2013-05-09 13:45:02 +0000124
bsalomon@google.com018f1792013-04-18 19:36:09 +0000125 // discard if coverage is zero
commit-bot@chromium.org824c3462013-10-10 06:30:18 +0000126 if (header.fDiscardIfZeroCoverage && !inCoverage.isOnes()) {
127 if (inCoverage.isZeros()) {
bsalomon@google.com018f1792013-04-18 19:36:09 +0000128 // This is unfortunate.
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000129 builder->fsCodeAppend("\tdiscard;\n");
bsalomon@google.com018f1792013-04-18 19:36:09 +0000130 } else {
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000131 builder->fsCodeAppendf("\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n\t\tdiscard;\n\t}\n",
132 inCoverage.c_str());
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000133 }
junov@google.comf93e7172011-03-31 21:26:24 +0000134 }
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000135
commit-bot@chromium.org949eef02013-10-01 18:43:29 +0000136 if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(header.fCoverageOutput)) {
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000137 const char* secondaryOutputName = builder->enableSecondaryOutput();
commit-bot@chromium.org410552a2013-09-30 15:30:27 +0000138
bsalomon@google.com018f1792013-04-18 19:36:09 +0000139 // default coeff to ones for kCoverage_DualSrcOutput
commit-bot@chromium.orga34995e2013-10-23 05:42:03 +0000140 GrGLSLExpr4 coeff(1);
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000141 if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCoverageOutput) {
bsalomon@google.com018f1792013-04-18 19:36:09 +0000142 // Get (1-A) into coeff
commit-bot@chromium.orga34995e2013-10-23 05:42:03 +0000143 coeff = GrGLSLExpr4::VectorCast(GrGLSLExpr1(1) - inColor.a());
commit-bot@chromium.org949eef02013-10-01 18:43:29 +0000144 } else if (GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput == header.fCoverageOutput) {
bsalomon@google.com018f1792013-04-18 19:36:09 +0000145 // Get (1-RGBA) into coeff
commit-bot@chromium.orga34995e2013-10-23 05:42:03 +0000146 coeff = GrGLSLExpr4(1) - inColor;
bsalomon@google.com018f1792013-04-18 19:36:09 +0000147 }
148 // Get coeff * coverage into modulate and then write that to the dual source output.
commit-bot@chromium.org824c3462013-10-10 06:30:18 +0000149 builder->fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, (coeff * inCoverage).c_str());
bsalomon@google.com018f1792013-04-18 19:36:09 +0000150 }
151
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000152 ///////////////////////////////////////////////////////////////////////////
153 // combine color and coverage as frag color
154
bsalomon@google.com5920ac22013-04-19 13:14:45 +0000155 // Get "color * coverage" into fragColor
commit-bot@chromium.orga34995e2013-10-23 05:42:03 +0000156 GrGLSLExpr4 fragColor = inColor * inCoverage;
bsalomon@google.com5920ac22013-04-19 13:14:45 +0000157 // Now tack on "+(1-coverage)dst onto the frag color if we were asked to do so.
commit-bot@chromium.org949eef02013-10-01 18:43:29 +0000158 if (GrGLProgramDesc::kCombineWithDst_CoverageOutput == header.fCoverageOutput) {
commit-bot@chromium.orga34995e2013-10-23 05:42:03 +0000159 GrGLSLExpr4 dstCoeff = GrGLSLExpr4(1) - inCoverage;
commit-bot@chromium.org824c3462013-10-10 06:30:18 +0000160
commit-bot@chromium.orga34995e2013-10-23 05:42:03 +0000161 GrGLSLExpr4 dstContribution = dstCoeff * GrGLSLExpr4(builder->dstColor());
commit-bot@chromium.org824c3462013-10-10 06:30:18 +0000162
163 fragColor = fragColor + dstContribution;
bsalomon@google.com5920ac22013-04-19 13:14:45 +0000164 }
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000165 builder->fsCodeAppendf("\t%s = %s;\n", builder->getColorOutputName(), fragColor.c_str());
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000166
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000167 if (!builder->finish(&fProgramID)) {
bsalomon@google.com91961302011-05-09 18:39:58 +0000168 return false;
169 }
170
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000171 fUniformHandles.fRTHeightUni = builder->getRTHeightUniform();
172 fUniformHandles.fDstCopyTopLeftUni = builder->getDstCopyTopLeftUniform();
173 fUniformHandles.fDstCopyScaleUni = builder->getDstCopyScaleUniform();
174 fUniformHandles.fColorUni = builder->getColorUniform();
175 fUniformHandles.fCoverageUni = builder->getCoverageUniform();
176 fUniformHandles.fDstCopySamplerUni = builder->getDstCopySamplerUniform();
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000177 // This must be called after we set fDstCopySamplerUni above.
178 this->initSamplerUniforms();
bsalomon@google.com91961302011-05-09 18:39:58 +0000179
180 return true;
181}
182
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000183void GrGLProgram::initSamplerUniforms() {
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +0000184 GL_CALL(UseProgram(fProgramID));
bsalomon@google.com34cccde2013-01-04 18:34:30 +0000185 GrGLint texUnitIdx = 0;
commit-bot@chromium.org7425c122013-08-14 18:14:19 +0000186 if (fUniformHandles.fDstCopySamplerUni.isValid()) {
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000187 fUniformManager.setSampler(fUniformHandles.fDstCopySamplerUni, texUnitIdx);
bsalomon@google.com804e9942013-06-06 18:04:38 +0000188 fDstCopyTexUnit = texUnitIdx++;
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000189 }
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000190 fColorEffects->initSamplers(fUniformManager, &texUnitIdx);
191 fCoverageEffects->initSamplers(fUniformManager, &texUnitIdx);
bsalomon@google.com91961302011-05-09 18:39:58 +0000192}
193
bsalomon@google.comeb715c82012-07-11 15:03:31 +0000194///////////////////////////////////////////////////////////////////////////////
junov@google.comf93e7172011-03-31 21:26:24 +0000195
commit-bot@chromium.org9188a152013-09-05 18:28:24 +0000196void GrGLProgram::setData(GrDrawState::BlendOptFlags blendOpts,
bsalomon@google.com2c84aa32013-06-06 20:28:57 +0000197 const GrEffectStage* colorStages[],
198 const GrEffectStage* coverageStages[],
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000199 const GrDeviceCoordTexture* dstCopy,
bsalomon@google.com91207482013-02-12 21:45:24 +0000200 SharedGLState* sharedState) {
commit-bot@chromium.org9188a152013-09-05 18:28:24 +0000201 const GrDrawState& drawState = fGpu->getDrawState();
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +0000202
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000203 GrColor color;
204 GrColor coverage;
205 if (blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag) {
206 color = 0;
207 coverage = 0;
208 } else if (blendOpts & GrDrawState::kEmitCoverage_BlendOptFlag) {
209 color = 0xffffffff;
210 coverage = drawState.getCoverage();
211 } else {
212 color = drawState.getColor();
213 coverage = drawState.getCoverage();
214 }
215
bsalomon@google.com91207482013-02-12 21:45:24 +0000216 this->setColor(drawState, color, sharedState);
217 this->setCoverage(drawState, coverage, sharedState);
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +0000218 this->setMatrixAndRenderTargetHeight(drawState);
bsalomon@google.com91207482013-02-12 21:45:24 +0000219
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000220 if (NULL != dstCopy) {
commit-bot@chromium.org7425c122013-08-14 18:14:19 +0000221 if (fUniformHandles.fDstCopyTopLeftUni.isValid()) {
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000222 fUniformManager.set2f(fUniformHandles.fDstCopyTopLeftUni,
223 static_cast<GrGLfloat>(dstCopy->offset().fX),
224 static_cast<GrGLfloat>(dstCopy->offset().fY));
225 fUniformManager.set2f(fUniformHandles.fDstCopyScaleUni,
226 1.f / dstCopy->texture()->width(),
227 1.f / dstCopy->texture()->height());
228 GrGLTexture* texture = static_cast<GrGLTexture*>(dstCopy->texture());
229 static GrTextureParams kParams; // the default is clamp, nearest filtering.
commit-bot@chromium.org9188a152013-09-05 18:28:24 +0000230 fGpu->bindTexture(fDstCopyTexUnit, kParams, texture);
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000231 } else {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000232 SkASSERT(!fUniformHandles.fDstCopyScaleUni.isValid());
233 SkASSERT(!fUniformHandles.fDstCopySamplerUni.isValid());
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000234 }
235 } else {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000236 SkASSERT(!fUniformHandles.fDstCopyTopLeftUni.isValid());
237 SkASSERT(!fUniformHandles.fDstCopyScaleUni.isValid());
238 SkASSERT(!fUniformHandles.fDstCopySamplerUni.isValid());
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000239 }
bsalomon@google.comc7818882013-03-20 19:19:53 +0000240
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000241 fColorEffects->setData(fGpu, fUniformManager, colorStages);
242 fCoverageEffects->setData(fGpu, fUniformManager, coverageStages);
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000243
244 if (!fHasVertexShader) {
245 fGpu->disableUnusedTexGen(fNumTexCoordSets);
246 }
skia.committer@gmail.com8ae714b2013-01-05 02:02:05 +0000247}
bsalomon@google.com91207482013-02-12 21:45:24 +0000248
249void GrGLProgram::setColor(const GrDrawState& drawState,
250 GrColor color,
251 SharedGLState* sharedState) {
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000252 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
jvanverth@google.com054ae992013-04-01 20:06:51 +0000253 if (!drawState.hasColorVertexAttribute()) {
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000254 switch (header.fColorInput) {
bsalomon@google.com31ec7982013-03-27 18:14:57 +0000255 case GrGLProgramDesc::kAttribute_ColorInput:
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000256 SkASSERT(-1 != header.fColorAttributeIndex);
jvanverth@google.com054ae992013-04-01 20:06:51 +0000257 if (sharedState->fConstAttribColor != color ||
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000258 sharedState->fConstAttribColorIndex != header.fColorAttributeIndex) {
bsalomon@google.com91207482013-02-12 21:45:24 +0000259 // OpenGL ES only supports the float varieties of glVertexAttrib
260 GrGLfloat c[4];
261 GrColorToRGBAFloat(color, c);
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000262 GL_CALL(VertexAttrib4fv(header.fColorAttributeIndex, c));
bsalomon@google.com91207482013-02-12 21:45:24 +0000263 sharedState->fConstAttribColor = color;
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000264 sharedState->fConstAttribColorIndex = header.fColorAttributeIndex;
bsalomon@google.com91207482013-02-12 21:45:24 +0000265 }
266 break;
bsalomon@google.com31ec7982013-03-27 18:14:57 +0000267 case GrGLProgramDesc::kUniform_ColorInput:
commit-bot@chromium.orga34995e2013-10-23 05:42:03 +0000268 if (fColor != color && fUniformHandles.fColorUni.isValid()) {
bsalomon@google.com91207482013-02-12 21:45:24 +0000269 // OpenGL ES doesn't support unsigned byte varieties of glUniform
270 GrGLfloat c[4];
271 GrColorToRGBAFloat(color, c);
bsalomon@google.com91207482013-02-12 21:45:24 +0000272 fUniformManager.set4fv(fUniformHandles.fColorUni, 0, 1, c);
273 fColor = color;
274 }
jvanverth@google.com054ae992013-04-01 20:06:51 +0000275 sharedState->fConstAttribColorIndex = -1;
bsalomon@google.com91207482013-02-12 21:45:24 +0000276 break;
bsalomon@google.com31ec7982013-03-27 18:14:57 +0000277 case GrGLProgramDesc::kSolidWhite_ColorInput:
278 case GrGLProgramDesc::kTransBlack_ColorInput:
jvanverth@google.com054ae992013-04-01 20:06:51 +0000279 sharedState->fConstAttribColorIndex = -1;
bsalomon@google.com91207482013-02-12 21:45:24 +0000280 break;
281 default:
282 GrCrash("Unknown color type.");
283 }
jvanverth@google.com054ae992013-04-01 20:06:51 +0000284 } else {
285 sharedState->fConstAttribColorIndex = -1;
bsalomon@google.com91207482013-02-12 21:45:24 +0000286 }
287}
288
289void GrGLProgram::setCoverage(const GrDrawState& drawState,
290 GrColor coverage,
291 SharedGLState* sharedState) {
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000292 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
jvanverth@google.com054ae992013-04-01 20:06:51 +0000293 if (!drawState.hasCoverageVertexAttribute()) {
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000294 switch (header.fCoverageInput) {
bsalomon@google.com31ec7982013-03-27 18:14:57 +0000295 case GrGLProgramDesc::kAttribute_ColorInput:
jvanverth@google.com054ae992013-04-01 20:06:51 +0000296 if (sharedState->fConstAttribCoverage != coverage ||
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000297 sharedState->fConstAttribCoverageIndex != header.fCoverageAttributeIndex) {
bsalomon@google.com91207482013-02-12 21:45:24 +0000298 // OpenGL ES only supports the float varieties of glVertexAttrib
299 GrGLfloat c[4];
300 GrColorToRGBAFloat(coverage, c);
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000301 GL_CALL(VertexAttrib4fv(header.fCoverageAttributeIndex, c));
bsalomon@google.com91207482013-02-12 21:45:24 +0000302 sharedState->fConstAttribCoverage = coverage;
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000303 sharedState->fConstAttribCoverageIndex = header.fCoverageAttributeIndex;
bsalomon@google.com91207482013-02-12 21:45:24 +0000304 }
305 break;
bsalomon@google.com31ec7982013-03-27 18:14:57 +0000306 case GrGLProgramDesc::kUniform_ColorInput:
bsalomon@google.com91207482013-02-12 21:45:24 +0000307 if (fCoverage != coverage) {
308 // OpenGL ES doesn't support unsigned byte varieties of glUniform
309 GrGLfloat c[4];
310 GrColorToRGBAFloat(coverage, c);
bsalomon@google.com91207482013-02-12 21:45:24 +0000311 fUniformManager.set4fv(fUniformHandles.fCoverageUni, 0, 1, c);
312 fCoverage = coverage;
313 }
jvanverth@google.com054ae992013-04-01 20:06:51 +0000314 sharedState->fConstAttribCoverageIndex = -1;
bsalomon@google.com91207482013-02-12 21:45:24 +0000315 break;
bsalomon@google.com31ec7982013-03-27 18:14:57 +0000316 case GrGLProgramDesc::kSolidWhite_ColorInput:
317 case GrGLProgramDesc::kTransBlack_ColorInput:
jvanverth@google.com054ae992013-04-01 20:06:51 +0000318 sharedState->fConstAttribCoverageIndex = -1;
bsalomon@google.com91207482013-02-12 21:45:24 +0000319 break;
320 default:
321 GrCrash("Unknown coverage type.");
322 }
jvanverth@google.com054ae992013-04-01 20:06:51 +0000323 } else {
324 sharedState->fConstAttribCoverageIndex = -1;
bsalomon@google.com91207482013-02-12 21:45:24 +0000325 }
326}
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +0000327
328void GrGLProgram::setMatrixAndRenderTargetHeight(const GrDrawState& drawState) {
329 const GrRenderTarget* rt = drawState.getRenderTarget();
330 SkISize size;
331 size.set(rt->width(), rt->height());
332
333 // Load the RT height uniform if it is needed to y-flip gl_FragCoord.
commit-bot@chromium.org7425c122013-08-14 18:14:19 +0000334 if (fUniformHandles.fRTHeightUni.isValid() &&
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +0000335 fMatrixState.fRenderTargetSize.fHeight != size.fHeight) {
336 fUniformManager.set1f(fUniformHandles.fRTHeightUni, SkIntToScalar(size.fHeight));
337 }
338
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000339 if (!fHasVertexShader) {
340 SkASSERT(!fUniformHandles.fViewMatrixUni.isValid());
341 fGpu->setProjectionMatrix(drawState.getViewMatrix(), size, rt->origin());
342 } else if (fMatrixState.fRenderTargetOrigin != rt->origin() ||
343 fMatrixState.fRenderTargetSize != size ||
344 !fMatrixState.fViewMatrix.cheapEqualTo(drawState.getViewMatrix())) {
345 SkASSERT(fUniformHandles.fViewMatrixUni.isValid());
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +0000346
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +0000347 fMatrixState.fViewMatrix = drawState.getViewMatrix();
348 fMatrixState.fRenderTargetSize = size;
349 fMatrixState.fRenderTargetOrigin = rt->origin();
commit-bot@chromium.org215a6822013-09-05 18:28:42 +0000350
351 GrGLfloat viewMatrix[3 * 3];
352 fMatrixState.getGLMatrix<3>(viewMatrix);
353 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, viewMatrix);
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +0000354 }
355}