aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrBlend.cpp
diff options
context:
space:
mode:
authorGravatar cdalton <cdalton@nvidia.com>2015-05-22 11:36:57 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-05-22 11:36:57 -0700
commit9a70920db22b6309c671f8e5d519bb95570e4414 (patch)
tree7c0d6884d581bd2860c2f4af5627de8dce3159d3 /src/gpu/GrBlend.cpp
parent2a97c55ae3b2b62fef2045e839600dc13b481c4c (diff)
Implement Porter Duff XP with a blend table
Removes the runtime logic used by PorterDuffXferProcessor to decide blend coeffs and shader outputs, and instead uses a compile-time constant table of pre-selected blend formulas. Introduces a new blend strategy for srcCoeff=0 that can apply coverage with a reverse subtract blend equation instead of dual source blending. Adds new macros in GrBlend.h to analyze blend formulas both runtime. Removes kSetCoverageDrawing_OptFlag and GrSimplifyBlend as they are no longer used. Adds a GM that verifies all xfermodes, including arithmetic, with the color/coverage invariants used by Porter Duff. Adds a unit test that verifies each Porter Duff formula with every color/coverage invariant. Major changes: * Uses a reverse subtract blend equation for coverage when srcCoeff=0 (clear, dst-out [Sa=1], dst-in, modulate). Platforms that don't support dual source blending no longer require a dst copy for dst-in and modulate. * Sets BlendInfo::fWriteColor to false when the blend does not modify the dst. GrGLGpu will now use glColorMask instead of blending for these modes (dst, dst-in [Sa=1], modulate ignored for [Sc=1]). * Converts all SA blend coeffs to One for opaque inputs, and ISA to Zero if there is also no coverage. (We keep ISA around when there is coverage because we use it to tweak alpha for coverage.) * Abandons solid white optimizations for the sake of simplicity (screen was the only mode that previous had solid white opts). Minor differences: * Inconsequential differences in opt flags (e.g. we now return kCanTweakAlphaForCoverage_OptFlag even when there is no coverage). * Src coeffs when the shader outputs 0. * IS2C vs IS2A when the secondary output is scalar. BUG=skia: Review URL: https://codereview.chromium.org/1124373002
Diffstat (limited to 'src/gpu/GrBlend.cpp')
-rw-r--r--src/gpu/GrBlend.cpp154
1 files changed, 0 insertions, 154 deletions
diff --git a/src/gpu/GrBlend.cpp b/src/gpu/GrBlend.cpp
deleted file mode 100644
index 52e335e9b0..0000000000
--- a/src/gpu/GrBlend.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-
-/*
- * Copyright 2013 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "GrBlend.h"
-
-static inline GrBlendCoeff swap_coeff_src_dst(GrBlendCoeff coeff) {
- switch (coeff) {
- case kDC_GrBlendCoeff:
- return kSC_GrBlendCoeff;
- case kIDC_GrBlendCoeff:
- return kISC_GrBlendCoeff;
- case kDA_GrBlendCoeff:
- return kSA_GrBlendCoeff;
- case kIDA_GrBlendCoeff:
- return kISA_GrBlendCoeff;
- case kSC_GrBlendCoeff:
- return kDC_GrBlendCoeff;
- case kISC_GrBlendCoeff:
- return kIDC_GrBlendCoeff;
- case kSA_GrBlendCoeff:
- return kDA_GrBlendCoeff;
- case kISA_GrBlendCoeff:
- return kIDA_GrBlendCoeff;
- default:
- return coeff;
- }
-}
-
-static inline unsigned saturated_add(unsigned a, unsigned b) {
- SkASSERT(a <= 255);
- SkASSERT(b <= 255);
- unsigned sum = a + b;
- if (sum > 255) {
- sum = 255;
- }
- return sum;
-}
-
-static GrColor add_colors(GrColor src, GrColor dst) {
- unsigned r = saturated_add(GrColorUnpackR(src), GrColorUnpackR(dst));
- unsigned g = saturated_add(GrColorUnpackG(src), GrColorUnpackG(dst));
- unsigned b = saturated_add(GrColorUnpackB(src), GrColorUnpackB(dst));
- unsigned a = saturated_add(GrColorUnpackA(src), GrColorUnpackA(dst));
- return GrColorPackRGBA(r, g, b, a);
-}
-
-static inline bool valid_color(uint32_t compFlags) {
- return (kRGBA_GrColorComponentFlags & compFlags) == kRGBA_GrColorComponentFlags;
-}
-
-static GrColor simplify_blend_term(GrBlendCoeff* srcCoeff,
- GrColor srcColor, uint32_t srcCompFlags,
- GrColor dstColor, uint32_t dstCompFlags,
- GrColor constantColor) {
-
- SkASSERT(!GrBlendCoeffRefsSrc(*srcCoeff));
- SkASSERT(srcCoeff);
-
- // Check whether srcCoeff can be reduced to kOne or kZero based on known color inputs.
- // We could pick out the coeff r,g,b,a values here and use them to compute the blend term color,
- // if possible, below but that is not implemented now.
- switch (*srcCoeff) {
- case kIDC_GrBlendCoeff:
- dstColor = ~dstColor; // fallthrough
- case kDC_GrBlendCoeff:
- if (valid_color(dstCompFlags)) {
- if (0xffffffff == dstColor) {
- *srcCoeff = kOne_GrBlendCoeff;
- } else if (0 == dstColor) {
- *srcCoeff = kZero_GrBlendCoeff;
- }
- }
- break;
-
- case kIDA_GrBlendCoeff:
- dstColor = ~dstColor; // fallthrough
- case kDA_GrBlendCoeff:
- if (kA_GrColorComponentFlag & dstCompFlags) {
- if (0xff == GrColorUnpackA(dstColor)) {
- *srcCoeff = kOne_GrBlendCoeff;
- } else if (0 == GrColorUnpackA(dstColor)) {
- *srcCoeff = kZero_GrBlendCoeff;
- }
- }
- break;
-
- case kIConstC_GrBlendCoeff:
- constantColor = ~constantColor; // fallthrough
- case kConstC_GrBlendCoeff:
- if (0xffffffff == constantColor) {
- *srcCoeff = kOne_GrBlendCoeff;
- } else if (0 == constantColor) {
- *srcCoeff = kZero_GrBlendCoeff;
- }
- break;
-
- case kIConstA_GrBlendCoeff:
- constantColor = ~constantColor; // fallthrough
- case kConstA_GrBlendCoeff:
- if (0xff == GrColorUnpackA(constantColor)) {
- *srcCoeff = kOne_GrBlendCoeff;
- } else if (0 == GrColorUnpackA(constantColor)) {
- *srcCoeff = kZero_GrBlendCoeff;
- }
- break;
-
- default:
- break;
- }
- // We may have invalidated these above and shouldn't read them again.
- SkDEBUGCODE(dstColor = constantColor = GrColor_ILLEGAL;)
-
- if (kZero_GrBlendCoeff == *srcCoeff || (valid_color(srcCompFlags) && 0 == srcColor)) {
- *srcCoeff = kZero_GrBlendCoeff;
- return 0;
- }
-
- if (kOne_GrBlendCoeff == *srcCoeff && valid_color(srcCompFlags)) {
- return srcColor;
- } else {
- return GrColor_ILLEGAL;
- }
-}
-
-GrColor GrSimplifyBlend(GrBlendCoeff* srcCoeff,
- GrBlendCoeff* dstCoeff,
- GrColor srcColor, uint32_t srcCompFlags,
- GrColor dstColor, uint32_t dstCompFlags,
- GrColor constantColor) {
- GrColor srcTermColor = simplify_blend_term(srcCoeff,
- srcColor, srcCompFlags,
- dstColor, dstCompFlags,
- constantColor);
-
- // We call the same function to simplify the dst blend coeff. We trick it out by swapping the
- // src and dst.
- GrBlendCoeff spoofedCoeff = swap_coeff_src_dst(*dstCoeff);
- GrColor dstTermColor = simplify_blend_term(&spoofedCoeff,
- dstColor, dstCompFlags,
- srcColor, srcCompFlags,
- constantColor);
- *dstCoeff = swap_coeff_src_dst(spoofedCoeff);
-
- if (GrColor_ILLEGAL != srcTermColor && GrColor_ILLEGAL != dstTermColor) {
- return add_colors(srcTermColor, dstTermColor);
- } else {
- return GrColor_ILLEGAL;
- }
-}