diff options
author | Greg Daniel <egdaniel@google.com> | 2017-05-19 10:56:46 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-05-19 17:20:33 +0000 |
commit | 6ebe4b9dbeab68ca3b6da61fd08f22cdc080267d (patch) | |
tree | 7cd35d97370f7d85d6422a71b044c62930d20cc6 /src/gpu/glsl | |
parent | 09e9f68625db41a1bdbac6738e2d4b57268ac5ca (diff) |
Fix gpu lcd blending to semi-correctly handle alpha coverage
Bug: skia:6606
Change-Id: I16ccd97f5d047eb7fddfed5310bf669e7435ccdd
Reviewed-on: https://skia-review.googlesource.com/17370
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
Diffstat (limited to 'src/gpu/glsl')
-rw-r--r-- | src/gpu/glsl/GrGLSLXferProcessor.cpp | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/src/gpu/glsl/GrGLSLXferProcessor.cpp b/src/gpu/glsl/GrGLSLXferProcessor.cpp index 545a9fd1f7..52656b181c 100644 --- a/src/gpu/glsl/GrGLSLXferProcessor.cpp +++ b/src/gpu/glsl/GrGLSLXferProcessor.cpp @@ -13,8 +13,22 @@ #include "glsl/GrGLSLProgramDataManager.h" #include "glsl/GrGLSLUniformHandler.h" +// This is only called for cases where we are doing LCD coverage and not using in shader blending. +// For these cases we assume the the src alpha is 1, thus we can just use the max for the alpha +// coverage since src alpha will always be greater than or equal to dst alpha. +static void adjust_for_lcd_coverage(GrGLSLXPFragmentBuilder* fragBuilder, + const char* srcCoverage, + const GrXferProcessor& proc) { + if (srcCoverage && proc.isLCD()) { + fragBuilder->codeAppendf("%s.a = max(max(%s.r, %s.g), %s.b);", + srcCoverage, srcCoverage, srcCoverage, srcCoverage); + } +} + + void GrGLSLXferProcessor::emitCode(const EmitArgs& args) { if (!args.fXP.willReadDstColor()) { + adjust_for_lcd_coverage(args.fXPFragBuilder, args.fInputCoverage, args.fXP); this->emitOutputsForBlendState(args); return; } @@ -111,13 +125,26 @@ void GrGLSLXferProcessor::DefaultCoverageModulation(GrGLSLXPFragmentBuilder* fra const GrXferProcessor& proc) { if (proc.dstReadUsesMixedSamples()) { if (srcCoverage) { + SkASSERT(!proc.isLCD()); fragBuilder->codeAppendf("%s *= %s;", outColor, srcCoverage); fragBuilder->codeAppendf("%s = %s;", outColorSecondary, srcCoverage); } else { fragBuilder->codeAppendf("%s = vec4(1.0);", outColorSecondary); } } else if (srcCoverage) { + if (proc.isLCD()) { + fragBuilder->codeAppendf("float lerpRed = mix(%s.a, %s.a, %s.r);", + dstColor, outColor, srcCoverage); + fragBuilder->codeAppendf("float lerpBlue = mix(%s.a, %s.a, %s.g);", + dstColor, outColor, srcCoverage); + fragBuilder->codeAppendf("float lerpGreen = mix(%s.a, %s.a, %s.b);", + dstColor, outColor, srcCoverage); + } fragBuilder->codeAppendf("%s = %s * %s + (vec4(1.0) - %s) * %s;", outColor, srcCoverage, outColor, srcCoverage, dstColor); + if (proc.isLCD()) { + fragBuilder->codeAppendf("%s.a = max(max(lerpRed, lerpBlue), lerpGreen);", outColor); + } } } + |