skia2/include/gpu/effects/GrPorterDuffXferProcessor.h

78 lines
3.0 KiB
C
Raw Normal View History

/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrPorterDuffXferProcessor_DEFINED
#define GrPorterDuffXferProcessor_DEFINED
#include "GrTypes.h"
#include "GrXferProcessor.h"
#include "SkBlendMode.h"
class GrProcOptInfo;
class GrPorterDuffXPFactory : public GrXPFactory {
public:
static sk_sp<GrXPFactory> Make(SkBlendMode mode);
void getInvariantBlendedColor(const GrProcOptInfo& colorPOI,
GrXPFactory::InvariantBlendedColor*) const override;
/** Because src-over is so common we special case it for performance reasons. If this returns
null then the SimpleSrcOverXP() below should be used. */
static GrXferProcessor* CreateSrcOverXferProcessor(const GrCaps& caps,
const GrPipelineOptimizations& optimizations,
bool hasMixedSamples,
const GrXferProcessor::DstTexture*);
/** This XP implements non-LCD src-over using hw blend with no optimizations. It is returned
by reference because it is global and its ref-cnting methods are not thread safe. */
static const GrXferProcessor& SimpleSrcOverXP();
static inline void SrcOverInvariantBlendedColor(
GrColor inputColor,
GrColorComponentFlags validColorFlags,
bool isOpaque,
GrXPFactory::InvariantBlendedColor* blendedColor) {
if (!isOpaque) {
blendedColor->fWillBlendWithDst = true;
blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags;
return;
}
blendedColor->fWillBlendWithDst = false;
blendedColor->fKnownColor = inputColor;
blendedColor->fKnownColorFlags = validColorFlags;
}
static bool SrcOverWillNeedDstTexture(const GrCaps&, const GrPipelineOptimizations&);
private:
GrPorterDuffXPFactory(SkBlendMode);
GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
const GrPipelineOptimizations& optimizations,
bool hasMixedSamples,
const DstTexture*) const override;
bool onWillReadDstColor(const GrCaps&, const GrPipelineOptimizations&) const override;
bool onIsEqual(const GrXPFactory& xpfBase) const override {
const GrPorterDuffXPFactory& xpf = xpfBase.cast<GrPorterDuffXPFactory>();
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. Separates out the dst read fallback into its own XP. 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: Committed: https://skia.googlesource.com/skia/+/9a70920db22b6309c671f8e5d519bb95570e4414 Review URL: https://codereview.chromium.org/1124373002
2015-05-27 22:08:33 +00:00
return fXfermode == xpf.fXfermode;
}
GR_DECLARE_XP_FACTORY_TEST;
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. Separates out the dst read fallback into its own XP. 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: Committed: https://skia.googlesource.com/skia/+/9a70920db22b6309c671f8e5d519bb95570e4414 Review URL: https://codereview.chromium.org/1124373002
2015-05-27 22:08:33 +00:00
static void TestGetXPOutputTypes(const GrXferProcessor*, int* outPrimary, int* outSecondary);
SkBlendMode fXfermode;
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. Separates out the dst read fallback into its own XP. 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: Committed: https://skia.googlesource.com/skia/+/9a70920db22b6309c671f8e5d519bb95570e4414 Review URL: https://codereview.chromium.org/1124373002
2015-05-27 22:08:33 +00:00
friend class GrPorterDuffTest; // for TestGetXPOutputTypes()
typedef GrXPFactory INHERITED;
};
#endif