gfx/skia/trunk/src/gpu/gl/GrGLProgram.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /*
michael@0 2 * Copyright 2011 Google Inc.
michael@0 3 *
michael@0 4 * Use of this source code is governed by a BSD-style license that can be
michael@0 5 * found in the LICENSE file.
michael@0 6 */
michael@0 7
michael@0 8 #include "GrGLProgram.h"
michael@0 9
michael@0 10 #include "GrAllocator.h"
michael@0 11 #include "GrEffect.h"
michael@0 12 #include "GrCoordTransform.h"
michael@0 13 #include "GrDrawEffect.h"
michael@0 14 #include "GrGLEffect.h"
michael@0 15 #include "GrGpuGL.h"
michael@0 16 #include "GrGLShaderVar.h"
michael@0 17 #include "GrGLSL.h"
michael@0 18 #include "SkXfermode.h"
michael@0 19
michael@0 20 #define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X)
michael@0 21 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(fGpu->glInterface(), R, X)
michael@0 22
michael@0 23 GrGLProgram* GrGLProgram::Create(GrGpuGL* gpu,
michael@0 24 const GrGLProgramDesc& desc,
michael@0 25 const GrEffectStage* colorStages[],
michael@0 26 const GrEffectStage* coverageStages[]) {
michael@0 27 GrGLProgram* program = SkNEW_ARGS(GrGLProgram, (gpu, desc, colorStages, coverageStages));
michael@0 28 if (!program->succeeded()) {
michael@0 29 delete program;
michael@0 30 program = NULL;
michael@0 31 }
michael@0 32 return program;
michael@0 33 }
michael@0 34
michael@0 35 GrGLProgram::GrGLProgram(GrGpuGL* gpu,
michael@0 36 const GrGLProgramDesc& desc,
michael@0 37 const GrEffectStage* colorStages[],
michael@0 38 const GrEffectStage* coverageStages[])
michael@0 39 : fGpu(gpu)
michael@0 40 , fUniformManager(gpu)
michael@0 41 , fHasVertexShader(false)
michael@0 42 , fNumTexCoordSets(0) {
michael@0 43 fDesc = desc;
michael@0 44 fProgramID = 0;
michael@0 45
michael@0 46 fDstCopyTexUnit = -1;
michael@0 47
michael@0 48 fColor = GrColor_ILLEGAL;
michael@0 49
michael@0 50 if (fDesc.getHeader().fHasVertexCode ||
michael@0 51 !fGpu->shouldUseFixedFunctionTexturing()) {
michael@0 52 GrGLFullShaderBuilder fullBuilder(fGpu, fUniformManager, fDesc);
michael@0 53 if (this->genProgram(&fullBuilder, colorStages, coverageStages)) {
michael@0 54 fUniformHandles.fViewMatrixUni = fullBuilder.getViewMatrixUniform();
michael@0 55 fHasVertexShader = true;
michael@0 56 }
michael@0 57 } else {
michael@0 58 GrGLFragmentOnlyShaderBuilder fragmentOnlyBuilder(fGpu, fUniformManager, fDesc);
michael@0 59 if (this->genProgram(&fragmentOnlyBuilder, colorStages, coverageStages)) {
michael@0 60 fNumTexCoordSets = fragmentOnlyBuilder.getNumTexCoordSets();
michael@0 61 }
michael@0 62 }
michael@0 63 }
michael@0 64
michael@0 65 GrGLProgram::~GrGLProgram() {
michael@0 66 if (fProgramID) {
michael@0 67 GL_CALL(DeleteProgram(fProgramID));
michael@0 68 }
michael@0 69 }
michael@0 70
michael@0 71 void GrGLProgram::abandon() {
michael@0 72 fProgramID = 0;
michael@0 73 }
michael@0 74
michael@0 75 void GrGLProgram::overrideBlend(GrBlendCoeff* srcCoeff,
michael@0 76 GrBlendCoeff* dstCoeff) const {
michael@0 77 switch (fDesc.getHeader().fCoverageOutput) {
michael@0 78 case GrGLProgramDesc::kModulate_CoverageOutput:
michael@0 79 break;
michael@0 80 // The prog will write a coverage value to the secondary
michael@0 81 // output and the dst is blended by one minus that value.
michael@0 82 case GrGLProgramDesc::kSecondaryCoverage_CoverageOutput:
michael@0 83 case GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput:
michael@0 84 case GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput:
michael@0 85 *dstCoeff = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
michael@0 86 break;
michael@0 87 case GrGLProgramDesc::kCombineWithDst_CoverageOutput:
michael@0 88 // We should only have set this if the blend was specified as (1, 0)
michael@0 89 SkASSERT(kOne_GrBlendCoeff == *srcCoeff && kZero_GrBlendCoeff == *dstCoeff);
michael@0 90 break;
michael@0 91 default:
michael@0 92 GrCrash("Unexpected coverage output");
michael@0 93 break;
michael@0 94 }
michael@0 95 }
michael@0 96
michael@0 97 bool GrGLProgram::genProgram(GrGLShaderBuilder* builder,
michael@0 98 const GrEffectStage* colorStages[],
michael@0 99 const GrEffectStage* coverageStages[]) {
michael@0 100 SkASSERT(0 == fProgramID);
michael@0 101
michael@0 102 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
michael@0 103
michael@0 104 // incoming color to current stage being processed.
michael@0 105 GrGLSLExpr4 inColor = builder->getInputColor();
michael@0 106
michael@0 107 fColorEffects.reset(
michael@0 108 builder->createAndEmitEffects(colorStages,
michael@0 109 fDesc.effectKeys(),
michael@0 110 fDesc.numColorEffects(),
michael@0 111 &inColor));
michael@0 112
michael@0 113 ///////////////////////////////////////////////////////////////////////////
michael@0 114 // compute the partial coverage
michael@0 115 GrGLSLExpr4 inCoverage = builder->getInputCoverage();
michael@0 116
michael@0 117 fCoverageEffects.reset(
michael@0 118 builder->createAndEmitEffects(coverageStages,
michael@0 119 fDesc.getEffectKeys() + fDesc.numColorEffects(),
michael@0 120 fDesc.numCoverageEffects(),
michael@0 121 &inCoverage));
michael@0 122
michael@0 123 if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(header.fCoverageOutput)) {
michael@0 124 const char* secondaryOutputName = builder->enableSecondaryOutput();
michael@0 125
michael@0 126 // default coeff to ones for kCoverage_DualSrcOutput
michael@0 127 GrGLSLExpr4 coeff(1);
michael@0 128 if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCoverageOutput) {
michael@0 129 // Get (1-A) into coeff
michael@0 130 coeff = GrGLSLExpr4::VectorCast(GrGLSLExpr1(1) - inColor.a());
michael@0 131 } else if (GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput == header.fCoverageOutput) {
michael@0 132 // Get (1-RGBA) into coeff
michael@0 133 coeff = GrGLSLExpr4(1) - inColor;
michael@0 134 }
michael@0 135 // Get coeff * coverage into modulate and then write that to the dual source output.
michael@0 136 builder->fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, (coeff * inCoverage).c_str());
michael@0 137 }
michael@0 138
michael@0 139 ///////////////////////////////////////////////////////////////////////////
michael@0 140 // combine color and coverage as frag color
michael@0 141
michael@0 142 // Get "color * coverage" into fragColor
michael@0 143 GrGLSLExpr4 fragColor = inColor * inCoverage;
michael@0 144 // Now tack on "+(1-coverage)dst onto the frag color if we were asked to do so.
michael@0 145 if (GrGLProgramDesc::kCombineWithDst_CoverageOutput == header.fCoverageOutput) {
michael@0 146 GrGLSLExpr4 dstCoeff = GrGLSLExpr4(1) - inCoverage;
michael@0 147
michael@0 148 GrGLSLExpr4 dstContribution = dstCoeff * GrGLSLExpr4(builder->dstColor());
michael@0 149
michael@0 150 fragColor = fragColor + dstContribution;
michael@0 151 }
michael@0 152 builder->fsCodeAppendf("\t%s = %s;\n", builder->getColorOutputName(), fragColor.c_str());
michael@0 153
michael@0 154 if (!builder->finish(&fProgramID)) {
michael@0 155 return false;
michael@0 156 }
michael@0 157
michael@0 158 fUniformHandles.fRTHeightUni = builder->getRTHeightUniform();
michael@0 159 fUniformHandles.fDstCopyTopLeftUni = builder->getDstCopyTopLeftUniform();
michael@0 160 fUniformHandles.fDstCopyScaleUni = builder->getDstCopyScaleUniform();
michael@0 161 fUniformHandles.fColorUni = builder->getColorUniform();
michael@0 162 fUniformHandles.fCoverageUni = builder->getCoverageUniform();
michael@0 163 fUniformHandles.fDstCopySamplerUni = builder->getDstCopySamplerUniform();
michael@0 164 // This must be called after we set fDstCopySamplerUni above.
michael@0 165 this->initSamplerUniforms();
michael@0 166
michael@0 167 return true;
michael@0 168 }
michael@0 169
michael@0 170 void GrGLProgram::initSamplerUniforms() {
michael@0 171 GL_CALL(UseProgram(fProgramID));
michael@0 172 GrGLint texUnitIdx = 0;
michael@0 173 if (fUniformHandles.fDstCopySamplerUni.isValid()) {
michael@0 174 fUniformManager.setSampler(fUniformHandles.fDstCopySamplerUni, texUnitIdx);
michael@0 175 fDstCopyTexUnit = texUnitIdx++;
michael@0 176 }
michael@0 177 fColorEffects->initSamplers(fUniformManager, &texUnitIdx);
michael@0 178 fCoverageEffects->initSamplers(fUniformManager, &texUnitIdx);
michael@0 179 }
michael@0 180
michael@0 181 ///////////////////////////////////////////////////////////////////////////////
michael@0 182
michael@0 183 void GrGLProgram::setData(GrDrawState::BlendOptFlags blendOpts,
michael@0 184 const GrEffectStage* colorStages[],
michael@0 185 const GrEffectStage* coverageStages[],
michael@0 186 const GrDeviceCoordTexture* dstCopy,
michael@0 187 SharedGLState* sharedState) {
michael@0 188 const GrDrawState& drawState = fGpu->getDrawState();
michael@0 189
michael@0 190 GrColor color;
michael@0 191 GrColor coverage;
michael@0 192 if (blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag) {
michael@0 193 color = 0;
michael@0 194 coverage = 0;
michael@0 195 } else if (blendOpts & GrDrawState::kEmitCoverage_BlendOptFlag) {
michael@0 196 color = 0xffffffff;
michael@0 197 coverage = drawState.getCoverageColor();
michael@0 198 } else {
michael@0 199 color = drawState.getColor();
michael@0 200 coverage = drawState.getCoverageColor();
michael@0 201 }
michael@0 202
michael@0 203 this->setColor(drawState, color, sharedState);
michael@0 204 this->setCoverage(drawState, coverage, sharedState);
michael@0 205 this->setMatrixAndRenderTargetHeight(drawState);
michael@0 206
michael@0 207 if (NULL != dstCopy) {
michael@0 208 if (fUniformHandles.fDstCopyTopLeftUni.isValid()) {
michael@0 209 fUniformManager.set2f(fUniformHandles.fDstCopyTopLeftUni,
michael@0 210 static_cast<GrGLfloat>(dstCopy->offset().fX),
michael@0 211 static_cast<GrGLfloat>(dstCopy->offset().fY));
michael@0 212 fUniformManager.set2f(fUniformHandles.fDstCopyScaleUni,
michael@0 213 1.f / dstCopy->texture()->width(),
michael@0 214 1.f / dstCopy->texture()->height());
michael@0 215 GrGLTexture* texture = static_cast<GrGLTexture*>(dstCopy->texture());
michael@0 216 static GrTextureParams kParams; // the default is clamp, nearest filtering.
michael@0 217 fGpu->bindTexture(fDstCopyTexUnit, kParams, texture);
michael@0 218 } else {
michael@0 219 SkASSERT(!fUniformHandles.fDstCopyScaleUni.isValid());
michael@0 220 SkASSERT(!fUniformHandles.fDstCopySamplerUni.isValid());
michael@0 221 }
michael@0 222 } else {
michael@0 223 SkASSERT(!fUniformHandles.fDstCopyTopLeftUni.isValid());
michael@0 224 SkASSERT(!fUniformHandles.fDstCopyScaleUni.isValid());
michael@0 225 SkASSERT(!fUniformHandles.fDstCopySamplerUni.isValid());
michael@0 226 }
michael@0 227
michael@0 228 fColorEffects->setData(fGpu, fUniformManager, colorStages);
michael@0 229 fCoverageEffects->setData(fGpu, fUniformManager, coverageStages);
michael@0 230
michael@0 231
michael@0 232 // TexGen state applies to the the fixed function vertex shader. For custom shaders, it's
michael@0 233 // ignored, so we don't need to change the texgen settings in that case.
michael@0 234 if (!fHasVertexShader) {
michael@0 235 fGpu->flushTexGenSettings(fNumTexCoordSets);
michael@0 236 }
michael@0 237 }
michael@0 238
michael@0 239 void GrGLProgram::setColor(const GrDrawState& drawState,
michael@0 240 GrColor color,
michael@0 241 SharedGLState* sharedState) {
michael@0 242 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
michael@0 243 if (!drawState.hasColorVertexAttribute()) {
michael@0 244 switch (header.fColorInput) {
michael@0 245 case GrGLProgramDesc::kAttribute_ColorInput:
michael@0 246 SkASSERT(-1 != header.fColorAttributeIndex);
michael@0 247 if (sharedState->fConstAttribColor != color ||
michael@0 248 sharedState->fConstAttribColorIndex != header.fColorAttributeIndex) {
michael@0 249 // OpenGL ES only supports the float varieties of glVertexAttrib
michael@0 250 GrGLfloat c[4];
michael@0 251 GrColorToRGBAFloat(color, c);
michael@0 252 GL_CALL(VertexAttrib4fv(header.fColorAttributeIndex, c));
michael@0 253 sharedState->fConstAttribColor = color;
michael@0 254 sharedState->fConstAttribColorIndex = header.fColorAttributeIndex;
michael@0 255 }
michael@0 256 break;
michael@0 257 case GrGLProgramDesc::kUniform_ColorInput:
michael@0 258 if (fColor != color && fUniformHandles.fColorUni.isValid()) {
michael@0 259 // OpenGL ES doesn't support unsigned byte varieties of glUniform
michael@0 260 GrGLfloat c[4];
michael@0 261 GrColorToRGBAFloat(color, c);
michael@0 262 fUniformManager.set4fv(fUniformHandles.fColorUni, 1, c);
michael@0 263 fColor = color;
michael@0 264 }
michael@0 265 sharedState->fConstAttribColorIndex = -1;
michael@0 266 break;
michael@0 267 case GrGLProgramDesc::kSolidWhite_ColorInput:
michael@0 268 case GrGLProgramDesc::kTransBlack_ColorInput:
michael@0 269 sharedState->fConstAttribColorIndex = -1;
michael@0 270 break;
michael@0 271 default:
michael@0 272 GrCrash("Unknown color type.");
michael@0 273 }
michael@0 274 } else {
michael@0 275 sharedState->fConstAttribColorIndex = -1;
michael@0 276 }
michael@0 277 }
michael@0 278
michael@0 279 void GrGLProgram::setCoverage(const GrDrawState& drawState,
michael@0 280 GrColor coverage,
michael@0 281 SharedGLState* sharedState) {
michael@0 282 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
michael@0 283 if (!drawState.hasCoverageVertexAttribute()) {
michael@0 284 switch (header.fCoverageInput) {
michael@0 285 case GrGLProgramDesc::kAttribute_ColorInput:
michael@0 286 if (sharedState->fConstAttribCoverage != coverage ||
michael@0 287 sharedState->fConstAttribCoverageIndex != header.fCoverageAttributeIndex) {
michael@0 288 // OpenGL ES only supports the float varieties of glVertexAttrib
michael@0 289 GrGLfloat c[4];
michael@0 290 GrColorToRGBAFloat(coverage, c);
michael@0 291 GL_CALL(VertexAttrib4fv(header.fCoverageAttributeIndex, c));
michael@0 292 sharedState->fConstAttribCoverage = coverage;
michael@0 293 sharedState->fConstAttribCoverageIndex = header.fCoverageAttributeIndex;
michael@0 294 }
michael@0 295 break;
michael@0 296 case GrGLProgramDesc::kUniform_ColorInput:
michael@0 297 if (fCoverage != coverage) {
michael@0 298 // OpenGL ES doesn't support unsigned byte varieties of glUniform
michael@0 299 GrGLfloat c[4];
michael@0 300 GrColorToRGBAFloat(coverage, c);
michael@0 301 fUniformManager.set4fv(fUniformHandles.fCoverageUni, 1, c);
michael@0 302 fCoverage = coverage;
michael@0 303 }
michael@0 304 sharedState->fConstAttribCoverageIndex = -1;
michael@0 305 break;
michael@0 306 case GrGLProgramDesc::kSolidWhite_ColorInput:
michael@0 307 case GrGLProgramDesc::kTransBlack_ColorInput:
michael@0 308 sharedState->fConstAttribCoverageIndex = -1;
michael@0 309 break;
michael@0 310 default:
michael@0 311 GrCrash("Unknown coverage type.");
michael@0 312 }
michael@0 313 } else {
michael@0 314 sharedState->fConstAttribCoverageIndex = -1;
michael@0 315 }
michael@0 316 }
michael@0 317
michael@0 318 void GrGLProgram::setMatrixAndRenderTargetHeight(const GrDrawState& drawState) {
michael@0 319 const GrRenderTarget* rt = drawState.getRenderTarget();
michael@0 320 SkISize size;
michael@0 321 size.set(rt->width(), rt->height());
michael@0 322
michael@0 323 // Load the RT height uniform if it is needed to y-flip gl_FragCoord.
michael@0 324 if (fUniformHandles.fRTHeightUni.isValid() &&
michael@0 325 fMatrixState.fRenderTargetSize.fHeight != size.fHeight) {
michael@0 326 fUniformManager.set1f(fUniformHandles.fRTHeightUni, SkIntToScalar(size.fHeight));
michael@0 327 }
michael@0 328
michael@0 329 if (!fHasVertexShader) {
michael@0 330 SkASSERT(!fUniformHandles.fViewMatrixUni.isValid());
michael@0 331 fGpu->setProjectionMatrix(drawState.getViewMatrix(), size, rt->origin());
michael@0 332 } else if (fMatrixState.fRenderTargetOrigin != rt->origin() ||
michael@0 333 fMatrixState.fRenderTargetSize != size ||
michael@0 334 !fMatrixState.fViewMatrix.cheapEqualTo(drawState.getViewMatrix())) {
michael@0 335 SkASSERT(fUniformHandles.fViewMatrixUni.isValid());
michael@0 336
michael@0 337 fMatrixState.fViewMatrix = drawState.getViewMatrix();
michael@0 338 fMatrixState.fRenderTargetSize = size;
michael@0 339 fMatrixState.fRenderTargetOrigin = rt->origin();
michael@0 340
michael@0 341 GrGLfloat viewMatrix[3 * 3];
michael@0 342 fMatrixState.getGLMatrix<3>(viewMatrix);
michael@0 343 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, viewMatrix);
michael@0 344 }
michael@0 345 }

mercurial