| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 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 "GrGLProgram.h" | 8 #include "GrGLProgram.h" |
| 9 | 9 |
| 10 #include "GrAllocator.h" | 10 #include "GrAllocator.h" |
| 11 #include "GrEffect.h" | 11 #include "GrEffect.h" |
| 12 #include "GrDrawEffect.h" | 12 #include "GrDrawEffect.h" |
| 13 #include "GrGLEffect.h" | 13 #include "GrGLEffect.h" |
| 14 #include "GrGpuGL.h" | 14 #include "GrGpuGL.h" |
| 15 #include "GrGLShaderVar.h" | 15 #include "GrGLShaderVar.h" |
| 16 #include "GrGLSL.h" | 16 #include "GrGLSL.h" |
| 17 #include "SkTrace.h" | |
| 18 #include "SkXfermode.h" | 17 #include "SkXfermode.h" |
| 19 | 18 |
| 20 #include "SkRTConf.h" | |
| 21 | |
| 22 SK_DEFINE_INST_COUNT(GrGLProgram) | 19 SK_DEFINE_INST_COUNT(GrGLProgram) |
| 23 | 20 |
| 24 #define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X) | 21 #define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X) |
| 25 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(fGpu->glInterface(), R, X) | 22 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(fGpu->glInterface(), R, X) |
| 26 | 23 |
| 27 SK_CONF_DECLARE(bool, c_PrintShaders, "gpu.printShaders", false, | |
| 28 "Print the source code for all shaders generated."); | |
| 29 | |
| 30 #define COL_ATTR_NAME "aColor" | |
| 31 #define COV_ATTR_NAME "aCoverage" | |
| 32 #define EDGE_ATTR_NAME "aEdge" | |
| 33 | |
| 34 namespace { | |
| 35 inline const char* declared_color_output_name() { return "fsColorOut"; } | |
| 36 inline const char* dual_source_output_name() { return "dualSourceOut"; } | |
| 37 } | |
| 38 | |
| 39 GrGLProgram* GrGLProgram::Create(GrGpuGL* gpu, | 24 GrGLProgram* GrGLProgram::Create(GrGpuGL* gpu, |
| 40 const GrGLProgramDesc& desc, | 25 const GrGLProgramDesc& desc, |
| 41 const GrEffectStage* colorStages[], | 26 const GrEffectStage* colorStages[], |
| 42 const GrEffectStage* coverageStages[]) { | 27 const GrEffectStage* coverageStages[]) { |
| 43 GrGLProgram* program = SkNEW_ARGS(GrGLProgram, (gpu, desc, colorStages, cove
rageStages)); | 28 GrGLProgram* program = SkNEW_ARGS(GrGLProgram, (gpu, desc, colorStages, cove
rageStages)); |
| 44 if (!program->succeeded()) { | 29 if (!program->succeeded()) { |
| 45 delete program; | 30 delete program; |
| 46 program = NULL; | 31 program = NULL; |
| 47 } | 32 } |
| 48 return program; | 33 return program; |
| 49 } | 34 } |
| 50 | 35 |
| 51 GrGLProgram::GrGLProgram(GrGpuGL* gpu, | 36 GrGLProgram::GrGLProgram(GrGpuGL* gpu, |
| 52 const GrGLProgramDesc& desc, | 37 const GrGLProgramDesc& desc, |
| 53 const GrEffectStage* colorStages[], | 38 const GrEffectStage* colorStages[], |
| 54 const GrEffectStage* coverageStages[]) | 39 const GrEffectStage* coverageStages[]) |
| 55 : fGpu(gpu) | 40 : fGpu(gpu) |
| 56 , fUniformManager(gpu) { | 41 , fUniformManager(gpu) { |
| 57 fDesc = desc; | 42 fDesc = desc; |
| 58 fVShaderID = 0; | |
| 59 fGShaderID = 0; | |
| 60 fFShaderID = 0; | |
| 61 fProgramID = 0; | 43 fProgramID = 0; |
| 62 | 44 |
| 63 fDstCopyTexUnit = -1; | 45 fDstCopyTexUnit = -1; |
| 64 | 46 |
| 65 fColor = GrColor_ILLEGAL; | 47 fColor = GrColor_ILLEGAL; |
| 66 fColorFilterColor = GrColor_ILLEGAL; | 48 fColorFilterColor = GrColor_ILLEGAL; |
| 67 | 49 |
| 68 fColorEffects.reset(desc.numColorEffects()); | 50 fColorEffects.reset(desc.numColorEffects()); |
| 69 fCoverageEffects.reset(desc.numCoverageEffects()); | 51 fCoverageEffects.reset(desc.numCoverageEffects()); |
| 70 | 52 |
| 71 this->genProgram(colorStages, coverageStages); | 53 this->genProgram(colorStages, coverageStages); |
| 72 } | 54 } |
| 73 | 55 |
| 74 GrGLProgram::~GrGLProgram() { | 56 GrGLProgram::~GrGLProgram() { |
| 75 if (fVShaderID) { | |
| 76 GL_CALL(DeleteShader(fVShaderID)); | |
| 77 } | |
| 78 if (fGShaderID) { | |
| 79 GL_CALL(DeleteShader(fGShaderID)); | |
| 80 } | |
| 81 if (fFShaderID) { | |
| 82 GL_CALL(DeleteShader(fFShaderID)); | |
| 83 } | |
| 84 if (fProgramID) { | 57 if (fProgramID) { |
| 85 GL_CALL(DeleteProgram(fProgramID)); | 58 GL_CALL(DeleteProgram(fProgramID)); |
| 86 } | 59 } |
| 87 } | 60 } |
| 88 | 61 |
| 89 void GrGLProgram::abandon() { | 62 void GrGLProgram::abandon() { |
| 90 fVShaderID = 0; | |
| 91 fGShaderID = 0; | |
| 92 fFShaderID = 0; | |
| 93 fProgramID = 0; | 63 fProgramID = 0; |
| 94 } | 64 } |
| 95 | 65 |
| 96 void GrGLProgram::overrideBlend(GrBlendCoeff* srcCoeff, | 66 void GrGLProgram::overrideBlend(GrBlendCoeff* srcCoeff, |
| 97 GrBlendCoeff* dstCoeff) const { | 67 GrBlendCoeff* dstCoeff) const { |
| 98 switch (fDesc.getHeader().fCoverageOutput) { | 68 switch (fDesc.getHeader().fCoverageOutput) { |
| 99 case GrGLProgramDesc::kModulate_CoverageOutput: | 69 case GrGLProgramDesc::kModulate_CoverageOutput: |
| 100 break; | 70 break; |
| 101 // The prog will write a coverage value to the secondary | 71 // The prog will write a coverage value to the secondary |
| 102 // output and the dst is blended by one minus that value. | 72 // output and the dst is blended by one minus that value. |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 SkString colorStr, constStr; | 182 SkString colorStr, constStr; |
| 213 blend_term_string(&colorStr, colorCoeff, filterColor, inColor, inColor); | 183 blend_term_string(&colorStr, colorCoeff, filterColor, inColor, inColor); |
| 214 blend_term_string(&constStr, uniformCoeff, filterColor, inColor, filterColor
); | 184 blend_term_string(&constStr, uniformCoeff, filterColor, inColor, filterColor
); |
| 215 | 185 |
| 216 SkString sum; | 186 SkString sum; |
| 217 GrGLSLAddf<4>(&sum, colorStr.c_str(), constStr.c_str()); | 187 GrGLSLAddf<4>(&sum, colorStr.c_str(), constStr.c_str()); |
| 218 builder->fsCodeAppendf("\t%s = %s;\n", outputVar, sum.c_str()); | 188 builder->fsCodeAppendf("\t%s = %s;\n", outputVar, sum.c_str()); |
| 219 } | 189 } |
| 220 } | 190 } |
| 221 | 191 |
| 222 GrSLConstantVec GrGLProgram::genInputColor(GrGLShaderBuilder* builder, SkString*
inColor) { | |
| 223 switch (fDesc.getHeader().fColorInput) { | |
| 224 case GrGLProgramDesc::kAttribute_ColorInput: { | |
| 225 GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertex
Builder(); | |
| 226 SkASSERT(NULL != vertexBuilder); | |
| 227 vertexBuilder->addAttribute(kVec4f_GrSLType, COL_ATTR_NAME); | |
| 228 const char *vsName, *fsName; | |
| 229 vertexBuilder->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName
); | |
| 230 vertexBuilder->vsCodeAppendf("\t%s = " COL_ATTR_NAME ";\n", vsName); | |
| 231 *inColor = fsName; | |
| 232 return kNone_GrSLConstantVec; | |
| 233 } | |
| 234 case GrGLProgramDesc::kUniform_ColorInput: { | |
| 235 const char* name; | |
| 236 fUniformHandles.fColorUni = builder->addUniform(GrGLShaderBuilder::k
Fragment_Visibility, | |
| 237 kVec4f_GrSLType, "Co
lor", &name); | |
| 238 *inColor = name; | |
| 239 return kNone_GrSLConstantVec; | |
| 240 } | |
| 241 case GrGLProgramDesc::kTransBlack_ColorInput: | |
| 242 inColor->reset(); | |
| 243 return kZeros_GrSLConstantVec; | |
| 244 case GrGLProgramDesc::kSolidWhite_ColorInput: | |
| 245 inColor->reset(); | |
| 246 return kOnes_GrSLConstantVec; | |
| 247 default: | |
| 248 GrCrash("Unknown color type."); | |
| 249 return kNone_GrSLConstantVec; | |
| 250 } | |
| 251 } | |
| 252 | |
| 253 GrSLConstantVec GrGLProgram::genInputCoverage(GrGLShaderBuilder* builder, SkStri
ng* inCoverage) { | |
| 254 switch (fDesc.getHeader().fCoverageInput) { | |
| 255 case GrGLProgramDesc::kAttribute_ColorInput: { | |
| 256 GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertex
Builder(); | |
| 257 SkASSERT(NULL != vertexBuilder); | |
| 258 vertexBuilder->addAttribute(kVec4f_GrSLType, COV_ATTR_NAME); | |
| 259 const char *vsName, *fsName; | |
| 260 vertexBuilder->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsN
ame); | |
| 261 vertexBuilder->vsCodeAppendf("\t%s = " COV_ATTR_NAME ";\n", vsName); | |
| 262 *inCoverage = fsName; | |
| 263 return kNone_GrSLConstantVec; | |
| 264 } | |
| 265 case GrGLProgramDesc::kUniform_ColorInput: { | |
| 266 const char* name; | |
| 267 fUniformHandles.fCoverageUni = | |
| 268 builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, | |
| 269 kVec4f_GrSLType, "Coverage", &name); | |
| 270 *inCoverage = name; | |
| 271 return kNone_GrSLConstantVec; | |
| 272 } | |
| 273 case GrGLProgramDesc::kTransBlack_ColorInput: | |
| 274 inCoverage->reset(); | |
| 275 return kZeros_GrSLConstantVec; | |
| 276 case GrGLProgramDesc::kSolidWhite_ColorInput: | |
| 277 inCoverage->reset(); | |
| 278 return kOnes_GrSLConstantVec; | |
| 279 default: | |
| 280 GrCrash("Unknown color type."); | |
| 281 return kNone_GrSLConstantVec; | |
| 282 } | |
| 283 } | |
| 284 | |
| 285 void GrGLProgram::genGeometryShader(GrGLShaderBuilder::VertexBuilder* vertexBuil
der) const { | |
| 286 #if GR_GL_EXPERIMENTAL_GS | |
| 287 // TODO: The builder should add all this glue code. | |
| 288 if (fDesc.getHeader().fExperimentalGS) { | |
| 289 SkASSERT(fGpu->glslGeneration() >= k150_GrGLSLGeneration); | |
| 290 vertexBuilder->fGSHeader.append("layout(triangles) in;\n" | |
| 291 "layout(triangle_strip, max_vertices = 6
) out;\n"); | |
| 292 vertexBuilder->gsCodeAppend("\tfor (int i = 0; i < 3; ++i) {\n" | |
| 293 "\t\tgl_Position = gl_in[i].gl_Position;\n")
; | |
| 294 if (fDesc.getHeader().fEmitsPointSize) { | |
| 295 vertexBuilder->gsCodeAppend("\t\tgl_PointSize = 1.0;\n"); | |
| 296 } | |
| 297 SkASSERT(vertexBuilder->fGSInputs.count() == vertexBuilder->fGSOutputs.c
ount()); | |
| 298 int count = vertexBuilder->fGSInputs.count(); | |
| 299 for (int i = 0; i < count; ++i) { | |
| 300 vertexBuilder->gsCodeAppendf("\t\t%s = %s[i];\n", | |
| 301 vertexBuilder->fGSOutputs[i].getName().
c_str(), | |
| 302 vertexBuilder->fGSInputs[i].getName().c
_str()); | |
| 303 } | |
| 304 vertexBuilder->gsCodeAppend("\t\tEmitVertex();\n" | |
| 305 "\t}\n" | |
| 306 "\tEndPrimitive();\n"); | |
| 307 } | |
| 308 #endif | |
| 309 } | |
| 310 | |
| 311 const char* GrGLProgram::adjustInColor(const SkString& inColor) const { | |
| 312 if (inColor.size()) { | |
| 313 return inColor.c_str(); | |
| 314 } else { | |
| 315 if (GrGLProgramDesc::kSolidWhite_ColorInput == fDesc.getHeader().fColorI
nput) { | |
| 316 return GrGLSLOnesVecf(4); | |
| 317 } else { | |
| 318 return GrGLSLZerosVecf(4); | |
| 319 } | |
| 320 } | |
| 321 } | |
| 322 | |
| 323 namespace { | 192 namespace { |
| 324 // prints a shader using params similar to glShaderSource | |
| 325 void print_shader(GrGLint stringCnt, | |
| 326 const GrGLchar** strings, | |
| 327 GrGLint* stringLengths) { | |
| 328 for (int i = 0; i < stringCnt; ++i) { | |
| 329 if (NULL == stringLengths || stringLengths[i] < 0) { | |
| 330 GrPrintf(strings[i]); | |
| 331 } else { | |
| 332 GrPrintf("%.*s", stringLengths[i], strings[i]); | |
| 333 } | |
| 334 } | |
| 335 } | |
| 336 | |
| 337 // Compiles a GL shader, returns shader ID or 0 if failed params have same meani
ng as glShaderSource | |
| 338 GrGLuint compile_shader(const GrGLInterface* gli, | |
| 339 GrGLenum type, | |
| 340 int stringCnt, | |
| 341 const char** strings, | |
| 342 int* stringLengths) { | |
| 343 SK_TRACE_EVENT1("GrGLProgram::CompileShader", | |
| 344 "stringCount", SkStringPrintf("%i", stringCnt).c_str()); | |
| 345 | |
| 346 GrGLuint shader; | |
| 347 GR_GL_CALL_RET(gli, shader, CreateShader(type)); | |
| 348 if (0 == shader) { | |
| 349 return 0; | |
| 350 } | |
| 351 | |
| 352 GrGLint compiled = GR_GL_INIT_ZERO; | |
| 353 GR_GL_CALL(gli, ShaderSource(shader, stringCnt, strings, stringLengths)); | |
| 354 GR_GL_CALL(gli, CompileShader(shader)); | |
| 355 GR_GL_CALL(gli, GetShaderiv(shader, GR_GL_COMPILE_STATUS, &compiled)); | |
| 356 | |
| 357 if (!compiled) { | |
| 358 GrGLint infoLen = GR_GL_INIT_ZERO; | |
| 359 GR_GL_CALL(gli, GetShaderiv(shader, GR_GL_INFO_LOG_LENGTH, &infoLen)); | |
| 360 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger | |
| 361 if (infoLen > 0) { | |
| 362 // retrieve length even though we don't need it to workaround bug in
chrome cmd buffer | |
| 363 // param validation. | |
| 364 GrGLsizei length = GR_GL_INIT_ZERO; | |
| 365 GR_GL_CALL(gli, GetShaderInfoLog(shader, infoLen+1, | |
| 366 &length, (char*)log.get())); | |
| 367 print_shader(stringCnt, strings, stringLengths); | |
| 368 GrPrintf("\n%s", log.get()); | |
| 369 } | |
| 370 SkDEBUGFAIL("Shader compilation failed!"); | |
| 371 GR_GL_CALL(gli, DeleteShader(shader)); | |
| 372 return 0; | |
| 373 } | |
| 374 return shader; | |
| 375 } | |
| 376 | |
| 377 // helper version of above for when shader is already flattened into a single Sk
String | |
| 378 GrGLuint compile_shader(const GrGLInterface* gli, GrGLenum type, const SkString&
shader) { | |
| 379 const GrGLchar* str = shader.c_str(); | |
| 380 int length = shader.size(); | |
| 381 return compile_shader(gli, type, 1, &str, &length); | |
| 382 } | |
| 383 | 193 |
| 384 void expand_known_value4f(SkString* string, GrSLConstantVec vec) { | 194 void expand_known_value4f(SkString* string, GrSLConstantVec vec) { |
| 385 SkASSERT(string->isEmpty() == (vec != kNone_GrSLConstantVec)); | 195 SkASSERT(string->isEmpty() == (vec != kNone_GrSLConstantVec)); |
| 386 switch (vec) { | 196 switch (vec) { |
| 387 case kNone_GrSLConstantVec: | 197 case kNone_GrSLConstantVec: |
| 388 break; | 198 break; |
| 389 case kZeros_GrSLConstantVec: | 199 case kZeros_GrSLConstantVec: |
| 390 *string = GrGLSLZerosVecf(4); | 200 *string = GrGLSLZerosVecf(4); |
| 391 break; | 201 break; |
| 392 case kOnes_GrSLConstantVec: | 202 case kOnes_GrSLConstantVec: |
| 393 *string = GrGLSLOnesVecf(4); | 203 *string = GrGLSLOnesVecf(4); |
| 394 break; | 204 break; |
| 395 } | 205 } |
| 396 } | 206 } |
| 397 | 207 |
| 398 } | 208 } |
| 399 | 209 |
| 400 // compiles all the shaders from builder and stores the shader IDs | |
| 401 bool GrGLProgram::compileShaders(const GrGLShaderBuilder& builder) { | |
| 402 | |
| 403 SkASSERT(!fVShaderID); | |
| 404 SkASSERT(!fGShaderID); | |
| 405 SkASSERT(!fFShaderID); | |
| 406 | |
| 407 SkString shader; | |
| 408 if (GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder.getVertexBuild
er()) { | |
| 409 vertexBuilder->vsGetShader(&shader); | |
| 410 if (c_PrintShaders) { | |
| 411 GrPrintf(shader.c_str()); | |
| 412 GrPrintf("\n"); | |
| 413 } | |
| 414 if (!(fVShaderID = compile_shader(fGpu->glInterface(), GR_GL_VERTEX_SHAD
ER, shader))) { | |
| 415 return false; | |
| 416 } | |
| 417 | |
| 418 #if GR_GL_EXPERIMENTAL_GS | |
| 419 if (fDesc.getHeader().fExperimentalGS) { | |
| 420 vertexBuilder->gsGetShader(&shader); | |
| 421 if (c_PrintShaders) { | |
| 422 GrPrintf(shader.c_str()); | |
| 423 GrPrintf("\n"); | |
| 424 } | |
| 425 if (!(fGShaderID = compile_shader(fGpu->glInterface(), GR_GL_GEOMETR
Y_SHADER, shader))) { | |
| 426 return false; | |
| 427 } | |
| 428 } | |
| 429 #endif | |
| 430 } | |
| 431 | |
| 432 builder.fsGetShader(&shader); | |
| 433 if (c_PrintShaders) { | |
| 434 GrPrintf(shader.c_str()); | |
| 435 GrPrintf("\n"); | |
| 436 } | |
| 437 if (!(fFShaderID = compile_shader(fGpu->glInterface(), GR_GL_FRAGMENT_SHADER
, shader))) { | |
| 438 return false; | |
| 439 } | |
| 440 | |
| 441 return true; | |
| 442 } | |
| 443 | |
| 444 bool GrGLProgram::genProgram(const GrEffectStage* colorStages[], | 210 bool GrGLProgram::genProgram(const GrEffectStage* colorStages[], |
| 445 const GrEffectStage* coverageStages[]) { | 211 const GrEffectStage* coverageStages[]) { |
| 446 SkASSERT(0 == fProgramID); | 212 SkASSERT(0 == fProgramID); |
| 447 | 213 |
| 448 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); | 214 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); |
| 449 | 215 |
| 450 bool needsVertexShader = true; | 216 bool needsVertexShader = true; |
| 451 | 217 |
| 452 GrGLShaderBuilder builder(fGpu->ctxInfo(), fUniformManager, fDesc, needsVert
exShader); | 218 GrGLShaderBuilder builder(fGpu, fUniformManager, fDesc, needsVertexShader); |
| 453 | |
| 454 if (GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder.getVertexBuild
er()) { | 219 if (GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder.getVertexBuild
er()) { |
| 455 const char* viewMName; | 220 fUniformHandles.fViewMatrixUni = vertexBuilder->getViewMatrixUniform(); |
| 456 fUniformHandles.fViewMatrixUni = builder.addUniform(GrGLShaderBuilder::k
Vertex_Visibility, | |
| 457 kMat33f_GrSLType, "V
iewM", &viewMName); | |
| 458 | |
| 459 vertexBuilder->vsCodeAppendf("\tvec3 pos3 = %s * vec3(%s, 1);\n" | |
| 460 "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\
n", | |
| 461 viewMName, vertexBuilder->positionAttribute
().c_str()); | |
| 462 | |
| 463 // we output point size in the GS if present | |
| 464 if (header.fEmitsPointSize | |
| 465 #if GR_GL_EXPERIMENTAL_GS | |
| 466 && !header.fExperimentalGS | |
| 467 #endif | |
| 468 ) { | |
| 469 vertexBuilder->vsCodeAppend("\tgl_PointSize = 1.0;\n"); | |
| 470 } | |
| 471 } | |
| 472 | |
| 473 // the dual source output has no canonical var name, have to | |
| 474 // declare an output, which is incompatible with gl_FragColor/gl_FragData. | |
| 475 bool dualSourceOutputWritten = false; | |
| 476 | |
| 477 GrGLShaderVar colorOutput; | |
| 478 bool isColorDeclared = GrGLSLSetupFSColorOuput(fGpu->glslGeneration(), | |
| 479 declared_color_output_name(), | |
| 480 &colorOutput); | |
| 481 if (isColorDeclared) { | |
| 482 builder.fsOutputAppend(colorOutput); | |
| 483 } | 221 } |
| 484 | 222 |
| 485 // incoming color to current stage being processed. | 223 // incoming color to current stage being processed. |
| 486 SkString inColor; | 224 SkString inColor = builder.getInputColor(); |
| 487 GrSLConstantVec knownColorValue = this->genInputColor(&builder, &inColor); | 225 GrSLConstantVec knownColorValue = builder.getKnownColorValue(); |
| 488 | 226 |
| 489 // Get the coeffs for the Mode-based color filter, determine if color is nee
ded. | 227 // Get the coeffs for the Mode-based color filter, determine if color is nee
ded. |
| 490 SkXfermode::Coeff colorCoeff; | 228 SkXfermode::Coeff colorCoeff; |
| 491 SkXfermode::Coeff filterColorCoeff; | 229 SkXfermode::Coeff filterColorCoeff; |
| 492 SkAssertResult( | 230 SkAssertResult( |
| 493 SkXfermode::ModeAsCoeff(static_cast<SkXfermode::Mode>(header.fColorFilte
rXfermode), | 231 SkXfermode::ModeAsCoeff(static_cast<SkXfermode::Mode>(header.fColorFilte
rXfermode), |
| 494 &filterColorCoeff, | 232 &filterColorCoeff, |
| 495 &colorCoeff)); | 233 &colorCoeff)); |
| 496 bool needColor, needFilterColor; | 234 bool needColor, needFilterColor; |
| 497 need_blend_inputs(filterColorCoeff, colorCoeff, &needFilterColor, &needColor
); | 235 need_blend_inputs(filterColorCoeff, colorCoeff, &needFilterColor, &needColor
); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 537 } else { | 275 } else { |
| 538 color = inColor.c_str(); | 276 color = inColor.c_str(); |
| 539 } | 277 } |
| 540 add_color_filter(&builder, "filteredColor", filterColorCoeff, | 278 add_color_filter(&builder, "filteredColor", filterColorCoeff, |
| 541 colorCoeff, colorFilterColorUniName, color); | 279 colorCoeff, colorFilterColorUniName, color); |
| 542 inColor = "filteredColor"; | 280 inColor = "filteredColor"; |
| 543 } | 281 } |
| 544 | 282 |
| 545 /////////////////////////////////////////////////////////////////////////// | 283 /////////////////////////////////////////////////////////////////////////// |
| 546 // compute the partial coverage | 284 // compute the partial coverage |
| 547 SkString inCoverage; | 285 SkString inCoverage = builder.getInputCoverage(); |
| 548 GrSLConstantVec knownCoverageValue = this->genInputCoverage(&builder, &inCov
erage); | 286 GrSLConstantVec knownCoverageValue = builder.getKnownCoverageValue(); |
| 549 | 287 |
| 550 for (int e = 0; e < fDesc.numCoverageEffects(); ++e) { | 288 for (int e = 0; e < fDesc.numCoverageEffects(); ++e) { |
| 551 effectUniformArrays[e] = &fCoverageEffects[e].fSamplerUnis; | 289 effectUniformArrays[e] = &fCoverageEffects[e].fSamplerUnis; |
| 552 } | 290 } |
| 553 | 291 |
| 554 builder.emitEffects(coverageStages, | 292 builder.emitEffects(coverageStages, |
| 555 fDesc.getEffectKeys() + fDesc.numColorEffects(), | 293 fDesc.getEffectKeys() + fDesc.numColorEffects(), |
| 556 fDesc.numCoverageEffects(), | 294 fDesc.numCoverageEffects(), |
| 557 &inCoverage, | 295 &inCoverage, |
| 558 &knownCoverageValue, | 296 &knownCoverageValue, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 569 builder.fsCodeAppend("\tdiscard;\n"); | 307 builder.fsCodeAppend("\tdiscard;\n"); |
| 570 } else { | 308 } else { |
| 571 builder.fsCodeAppendf("\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n\
t\tdiscard;\n\t}\n", | 309 builder.fsCodeAppendf("\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n\
t\tdiscard;\n\t}\n", |
| 572 inCoverage.c_str()); | 310 inCoverage.c_str()); |
| 573 } | 311 } |
| 574 } | 312 } |
| 575 | 313 |
| 576 GrGLProgramDesc::CoverageOutput coverageOutput = | 314 GrGLProgramDesc::CoverageOutput coverageOutput = |
| 577 static_cast<GrGLProgramDesc::CoverageOutput>(header.fCoverageOutput); | 315 static_cast<GrGLProgramDesc::CoverageOutput>(header.fCoverageOutput); |
| 578 if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(coverageOutput)) { | 316 if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(coverageOutput)) { |
| 579 builder.fsOutputAppend().set(kVec4f_GrSLType, | 317 const char* secondaryOutputName = builder.enableSecondaryOutput(); |
| 580 GrGLShaderVar::kOut_TypeModifier, | 318 |
| 581 dual_source_output_name()); | |
| 582 // default coeff to ones for kCoverage_DualSrcOutput | 319 // default coeff to ones for kCoverage_DualSrcOutput |
| 583 SkString coeff; | 320 SkString coeff; |
| 584 GrSLConstantVec knownCoeffValue = kOnes_GrSLConstantVec; | 321 GrSLConstantVec knownCoeffValue = kOnes_GrSLConstantVec; |
| 585 if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCov
erageOutput) { | 322 if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCov
erageOutput) { |
| 586 // Get (1-A) into coeff | 323 // Get (1-A) into coeff |
| 587 SkString inColorAlpha; | 324 SkString inColorAlpha; |
| 588 GrGLSLGetComponent4f(&inColorAlpha, | 325 GrGLSLGetComponent4f(&inColorAlpha, |
| 589 inColor.c_str(), | 326 inColor.c_str(), |
| 590 kA_GrColorComponentFlag, | 327 kA_GrColorComponentFlag, |
| 591 knownColorValue, | 328 knownColorValue, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 606 true); | 343 true); |
| 607 } | 344 } |
| 608 // Get coeff * coverage into modulate and then write that to the dual so
urce output. | 345 // Get coeff * coverage into modulate and then write that to the dual so
urce output. |
| 609 SkString modulate; | 346 SkString modulate; |
| 610 GrGLSLModulatef<4>(&modulate, | 347 GrGLSLModulatef<4>(&modulate, |
| 611 coeff.c_str(), | 348 coeff.c_str(), |
| 612 inCoverage.c_str(), | 349 inCoverage.c_str(), |
| 613 knownCoeffValue, | 350 knownCoeffValue, |
| 614 knownCoverageValue, | 351 knownCoverageValue, |
| 615 false); | 352 false); |
| 616 builder.fsCodeAppendf("\t%s = %s;\n", dual_source_output_name(), modulat
e.c_str()); | 353 builder.fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, modulate.c_st
r()); |
| 617 dualSourceOutputWritten = true; | |
| 618 } | 354 } |
| 619 | 355 |
| 620 /////////////////////////////////////////////////////////////////////////// | 356 /////////////////////////////////////////////////////////////////////////// |
| 621 // combine color and coverage as frag color | 357 // combine color and coverage as frag color |
| 622 | 358 |
| 623 // Get "color * coverage" into fragColor | 359 // Get "color * coverage" into fragColor |
| 624 SkString fragColor; | 360 SkString fragColor; |
| 625 GrSLConstantVec knownFragColorValue = GrGLSLModulatef<4>(&fragColor, | 361 GrSLConstantVec knownFragColorValue = GrGLSLModulatef<4>(&fragColor, |
| 626 inColor.c_str(), | 362 inColor.c_str(), |
| 627 inCoverage.c_str(), | 363 inCoverage.c_str(), |
| (...skipping 20 matching lines...) Expand all Loading... |
| 648 fragColor.reset(); | 384 fragColor.reset(); |
| 649 GrGLSLAddf<4>(&fragColor, | 385 GrGLSLAddf<4>(&fragColor, |
| 650 oldFragColor.c_str(), | 386 oldFragColor.c_str(), |
| 651 dstContribution.c_str(), | 387 dstContribution.c_str(), |
| 652 knownFragColorValue, | 388 knownFragColorValue, |
| 653 knownDstContributionValue, | 389 knownDstContributionValue, |
| 654 false); | 390 false); |
| 655 } else { | 391 } else { |
| 656 expand_known_value4f(&fragColor, knownFragColorValue); | 392 expand_known_value4f(&fragColor, knownFragColorValue); |
| 657 } | 393 } |
| 658 builder.fsCodeAppendf("\t%s = %s;\n", colorOutput.getName().c_str(), fragCol
or.c_str()); | 394 builder.fsCodeAppendf("\t%s = %s;\n", builder.getColorOutputName(), fragColo
r.c_str()); |
| 659 | 395 |
| 660 /////////////////////////////////////////////////////////////////////////// | 396 if (!builder.finish(&fProgramID)) { |
| 661 // insert GS | |
| 662 #ifdef SK_DEBUG | |
| 663 if (GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder.getVertexBuild
er()) { | |
| 664 this->genGeometryShader(vertexBuilder); | |
| 665 } | |
| 666 #endif | |
| 667 | |
| 668 /////////////////////////////////////////////////////////////////////////// | |
| 669 // compile and setup attribs and unis | |
| 670 | |
| 671 if (!this->compileShaders(builder)) { | |
| 672 return false; | 397 return false; |
| 673 } | 398 } |
| 674 | 399 |
| 675 if (!this->bindOutputsAttribsAndLinkProgram(builder, | |
| 676 isColorDeclared, | |
| 677 dualSourceOutputWritten)) { | |
| 678 return false; | |
| 679 } | |
| 680 | |
| 681 builder.finished(fProgramID); | |
| 682 fUniformHandles.fRTHeightUni = builder.getRTHeightUniform(); | 400 fUniformHandles.fRTHeightUni = builder.getRTHeightUniform(); |
| 683 fUniformHandles.fDstCopyTopLeftUni = builder.getDstCopyTopLeftUniform(); | 401 fUniformHandles.fDstCopyTopLeftUni = builder.getDstCopyTopLeftUniform(); |
| 684 fUniformHandles.fDstCopyScaleUni = builder.getDstCopyScaleUniform(); | 402 fUniformHandles.fDstCopyScaleUni = builder.getDstCopyScaleUniform(); |
| 403 fUniformHandles.fColorUni = builder.getColorUniform(); |
| 404 fUniformHandles.fCoverageUni = builder.getCoverageUniform(); |
| 685 fUniformHandles.fDstCopySamplerUni = builder.getDstCopySamplerUniform(); | 405 fUniformHandles.fDstCopySamplerUni = builder.getDstCopySamplerUniform(); |
| 686 // This must be called after we set fDstCopySamplerUni above. | 406 // This must be called after we set fDstCopySamplerUni above. |
| 687 this->initSamplerUniforms(); | 407 this->initSamplerUniforms(); |
| 688 | 408 |
| 689 return true; | 409 return true; |
| 690 } | 410 } |
| 691 | 411 |
| 692 bool GrGLProgram::bindOutputsAttribsAndLinkProgram(const GrGLShaderBuilder& buil
der, | |
| 693 bool bindColorOut, | |
| 694 bool bindDualSrcOut) { | |
| 695 GL_CALL_RET(fProgramID, CreateProgram()); | |
| 696 if (!fProgramID) { | |
| 697 return false; | |
| 698 } | |
| 699 | |
| 700 if (fVShaderID) { | |
| 701 GL_CALL(AttachShader(fProgramID, fVShaderID)); | |
| 702 } | |
| 703 if (fGShaderID) { | |
| 704 GL_CALL(AttachShader(fProgramID, fGShaderID)); | |
| 705 } | |
| 706 GL_CALL(AttachShader(fProgramID, fFShaderID)); | |
| 707 | |
| 708 if (bindColorOut) { | |
| 709 GL_CALL(BindFragDataLocation(fProgramID, 0, declared_color_output_name()
)); | |
| 710 } | |
| 711 if (bindDualSrcOut) { | |
| 712 GL_CALL(BindFragDataLocationIndexed(fProgramID, 0, 1, dual_source_output
_name())); | |
| 713 } | |
| 714 | |
| 715 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); | |
| 716 | |
| 717 // Bind the attrib locations to same values for all shaders | |
| 718 if (GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder.getVertexBuild
er()) { | |
| 719 GL_CALL(BindAttribLocation(fProgramID, | |
| 720 header.fPositionAttributeIndex, | |
| 721 vertexBuilder->positionAttribute().c_str())); | |
| 722 if (-1 != header.fLocalCoordAttributeIndex) { | |
| 723 GL_CALL(BindAttribLocation(fProgramID, | |
| 724 header.fLocalCoordAttributeIndex, | |
| 725 vertexBuilder->localCoordsAttribute().c_s
tr())); | |
| 726 } | |
| 727 if (-1 != header.fColorAttributeIndex) { | |
| 728 GL_CALL(BindAttribLocation(fProgramID, header.fColorAttributeIndex,
COL_ATTR_NAME)); | |
| 729 } | |
| 730 if (-1 != header.fCoverageAttributeIndex) { | |
| 731 GL_CALL(BindAttribLocation(fProgramID, header.fCoverageAttributeInde
x, COV_ATTR_NAME)); | |
| 732 } | |
| 733 | |
| 734 const GrGLShaderBuilder::VertexBuilder::AttributePair* attribEnd = verte
xBuilder->getEffectAttributes().end(); | |
| 735 for (const GrGLShaderBuilder::VertexBuilder::AttributePair* attrib = ver
texBuilder->getEffectAttributes().begin(); | |
| 736 attrib != attribEnd; | |
| 737 ++attrib) { | |
| 738 GL_CALL(BindAttribLocation(fProgramID, attrib->fIndex, attrib->fNam
e.c_str())); | |
| 739 } | |
| 740 } | |
| 741 | |
| 742 GL_CALL(LinkProgram(fProgramID)); | |
| 743 | |
| 744 GrGLint linked = GR_GL_INIT_ZERO; | |
| 745 GL_CALL(GetProgramiv(fProgramID, GR_GL_LINK_STATUS, &linked)); | |
| 746 if (!linked) { | |
| 747 GrGLint infoLen = GR_GL_INIT_ZERO; | |
| 748 GL_CALL(GetProgramiv(fProgramID, GR_GL_INFO_LOG_LENGTH, &infoLen)); | |
| 749 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger | |
| 750 if (infoLen > 0) { | |
| 751 // retrieve length even though we don't need it to workaround | |
| 752 // bug in chrome cmd buffer param validation. | |
| 753 GrGLsizei length = GR_GL_INIT_ZERO; | |
| 754 GL_CALL(GetProgramInfoLog(fProgramID, | |
| 755 infoLen+1, | |
| 756 &length, | |
| 757 (char*)log.get())); | |
| 758 GrPrintf((char*)log.get()); | |
| 759 } | |
| 760 SkDEBUGFAIL("Error linking program"); | |
| 761 GL_CALL(DeleteProgram(fProgramID)); | |
| 762 fProgramID = 0; | |
| 763 return false; | |
| 764 } | |
| 765 return true; | |
| 766 } | |
| 767 | |
| 768 void GrGLProgram::initSamplerUniforms() { | 412 void GrGLProgram::initSamplerUniforms() { |
| 769 GL_CALL(UseProgram(fProgramID)); | 413 GL_CALL(UseProgram(fProgramID)); |
| 770 GrGLint texUnitIdx = 0; | 414 GrGLint texUnitIdx = 0; |
| 771 if (fUniformHandles.fDstCopySamplerUni.isValid()) { | 415 if (fUniformHandles.fDstCopySamplerUni.isValid()) { |
| 772 fUniformManager.setSampler(fUniformHandles.fDstCopySamplerUni, texUnitId
x); | 416 fUniformManager.setSampler(fUniformHandles.fDstCopySamplerUni, texUnitId
x); |
| 773 fDstCopyTexUnit = texUnitIdx++; | 417 fDstCopyTexUnit = texUnitIdx++; |
| 774 } | 418 } |
| 775 | 419 |
| 776 for (int e = 0; e < fColorEffects.count(); ++e) { | 420 for (int e = 0; e < fColorEffects.count(); ++e) { |
| 777 this->initEffectSamplerUniforms(&fColorEffects[e], &texUnitIdx); | 421 this->initEffectSamplerUniforms(&fColorEffects[e], &texUnitIdx); |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 983 | 627 |
| 984 fMatrixState.fViewMatrix = drawState.getViewMatrix(); | 628 fMatrixState.fViewMatrix = drawState.getViewMatrix(); |
| 985 fMatrixState.fRenderTargetSize = size; | 629 fMatrixState.fRenderTargetSize = size; |
| 986 fMatrixState.fRenderTargetOrigin = rt->origin(); | 630 fMatrixState.fRenderTargetOrigin = rt->origin(); |
| 987 | 631 |
| 988 GrGLfloat viewMatrix[3 * 3]; | 632 GrGLfloat viewMatrix[3 * 3]; |
| 989 fMatrixState.getGLMatrix<3>(viewMatrix); | 633 fMatrixState.getGLMatrix<3>(viewMatrix); |
| 990 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, viewMatrix); | 634 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, viewMatrix); |
| 991 } | 635 } |
| 992 } | 636 } |
| OLD | NEW |