aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/glsl
diff options
context:
space:
mode:
authorGravatar Greg Daniel <egdaniel@google.com>2017-05-19 10:56:46 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-05-19 17:20:33 +0000
commit6ebe4b9dbeab68ca3b6da61fd08f22cdc080267d (patch)
tree7cd35d97370f7d85d6422a71b044c62930d20cc6 /src/gpu/glsl
parent09e9f68625db41a1bdbac6738e2d4b57268ac5ca (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.cpp27
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);
+ }
}
}
+