From 6ebe4b9dbeab68ca3b6da61fd08f22cdc080267d Mon Sep 17 00:00:00 2001 From: Greg Daniel Date: Fri, 19 May 2017 10:56:46 -0400 Subject: 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 Commit-Queue: Greg Daniel --- src/gpu/glsl/GrGLSLXferProcessor.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'src/gpu/glsl') 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); + } } } + -- cgit v1.2.3