Remove the need for asCoeff in SkXfermode.
BUG=skia: Review URL: https://codereview.chromium.org/864833002
This commit is contained in:
parent
2dca817edb
commit
dcfb7cf336
@ -57,29 +57,6 @@ public:
|
||||
kCoeffCount
|
||||
};
|
||||
|
||||
/** If the xfermode can be expressed as an equation using the coefficients
|
||||
in Coeff, then asCoeff() returns true, and sets (if not null) src and
|
||||
dst accordingly.
|
||||
|
||||
result = src_coeff * src_color + dst_coeff * dst_color;
|
||||
|
||||
As examples, here are some of the porterduff coefficients
|
||||
|
||||
MODE SRC_COEFF DST_COEFF
|
||||
clear zero zero
|
||||
src one zero
|
||||
dst zero one
|
||||
srcover one isa
|
||||
dstover ida one
|
||||
*/
|
||||
virtual bool asCoeff(Coeff* src, Coeff* dst) const;
|
||||
|
||||
/**
|
||||
* The same as calling xfermode->asCoeff(..), except that this also checks
|
||||
* if the xfermode is NULL, and if so, treats it as kSrcOver_Mode.
|
||||
*/
|
||||
static bool AsCoeff(const SkXfermode*, Coeff* src, Coeff* dst);
|
||||
|
||||
/** List of predefined xfermodes.
|
||||
The algebra for the modes uses the following symbols:
|
||||
Sa, Sc - source alpha and color
|
||||
@ -190,6 +167,41 @@ public:
|
||||
return AsMode(xfer, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the xfer mode can support treating coverage as alpha
|
||||
*/
|
||||
virtual bool supportsCoverageAsAlpha() const;
|
||||
|
||||
/**
|
||||
* The same as calling xfermode->supportsCoverageAsAlpha(), except that this also checks if
|
||||
* the xfermode is NULL, and if so, treats it as kSrcOver_Mode.
|
||||
*/
|
||||
static bool SupportsCoverageAsAlpha(const SkXfermode* xfer);
|
||||
|
||||
enum SrcColorOpacity {
|
||||
// The src color is known to be opaque (alpha == 255)
|
||||
kOpaque_SrcColorOpacity = 0,
|
||||
// The src color is known to be fully transparent (color == 0)
|
||||
kTransparentBlack_SrcColorOpacity = 1,
|
||||
// The src alpha is known to be fully transparent (alpha == 0)
|
||||
kTransparentAlpha_SrcColorOpacity = 2,
|
||||
// The src color opacity is unknown
|
||||
kUnknown_SrcColorOpacity = 3
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns whether or not the result of the draw with the xfer mode will be opaque or not. The
|
||||
* input to this call is an enum describing known information about the opacity of the src color
|
||||
* that will be given to the xfer mode.
|
||||
*/
|
||||
virtual bool isOpaque(SrcColorOpacity opacityType) const;
|
||||
|
||||
/**
|
||||
* The same as calling xfermode->isOpaque(...), except that this also checks if
|
||||
* the xfermode is NULL, and if so, treats it as kSrcOver_Mode.
|
||||
*/
|
||||
static bool IsOpaque(const SkXfermode* xfer, SrcColorOpacity opacityType);
|
||||
|
||||
/** Implemented by a subclass to support use as an image filter in the GPU backend. When used as
|
||||
an image filter the xfer mode blends the source color against a background texture rather
|
||||
than the destination. It is implemented as a fragment processor. This can be called with
|
||||
|
@ -936,22 +936,6 @@ static SkScalar fast_len(const SkVector& vec) {
|
||||
return x + SkScalarHalf(y);
|
||||
}
|
||||
|
||||
static bool xfermodeSupportsCoverageAsAlpha(SkXfermode* xfer) {
|
||||
SkXfermode::Coeff dc;
|
||||
if (!SkXfermode::AsCoeff(xfer, NULL, &dc)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (dc) {
|
||||
case SkXfermode::kOne_Coeff:
|
||||
case SkXfermode::kISA_Coeff:
|
||||
case SkXfermode::kISC_Coeff:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool SkDrawTreatAAStrokeAsHairline(SkScalar strokeWidth, const SkMatrix& matrix,
|
||||
SkScalar* coverage) {
|
||||
SkASSERT(strokeWidth > 0);
|
||||
@ -1063,7 +1047,7 @@ void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint,
|
||||
if (SkDrawTreatAsHairline(origPaint, *matrix, &coverage)) {
|
||||
if (SK_Scalar1 == coverage) {
|
||||
paint.writable()->setStrokeWidth(0);
|
||||
} else if (xfermodeSupportsCoverageAsAlpha(origPaint.getXfermode())) {
|
||||
} else if (SkXfermode::SupportsCoverageAsAlpha(origPaint.getXfermode())) {
|
||||
U8CPU newAlpha;
|
||||
#if 0
|
||||
newAlpha = SkToU8(SkScalarRoundToInt(coverage *
|
||||
|
@ -13,65 +13,28 @@
|
||||
#include "SkShader.h"
|
||||
|
||||
bool isPaintOpaque(const SkPaint* paint, SkPaintBitmapOpacity contentType) {
|
||||
// TODO: SkXfermode should have a virtual isOpaque method, which would
|
||||
// make it possible to test modes that do not have a Coeff representation.
|
||||
|
||||
if (!paint) {
|
||||
return contentType != kUnknown_SkPaintBitmapOpacity;
|
||||
}
|
||||
SkXfermode::SrcColorOpacity opacityType = SkXfermode::kUnknown_SrcColorOpacity;
|
||||
|
||||
SkXfermode::Coeff srcCoeff, dstCoeff;
|
||||
if (SkXfermode::AsCoeff(paint->getXfermode(), &srcCoeff, &dstCoeff)){
|
||||
if (SkXfermode::kDA_Coeff == srcCoeff || SkXfermode::kDC_Coeff == srcCoeff ||
|
||||
SkXfermode::kIDA_Coeff == srcCoeff || SkXfermode::kIDC_Coeff == srcCoeff) {
|
||||
return false;
|
||||
}
|
||||
switch (dstCoeff) {
|
||||
case SkXfermode::kZero_Coeff:
|
||||
return true;
|
||||
case SkXfermode::kISA_Coeff:
|
||||
if (paint->getAlpha() != 255) {
|
||||
break;
|
||||
}
|
||||
if (contentType == kUnknown_SkPaintBitmapOpacity) {
|
||||
break;
|
||||
} else if (paint->getShader() && !paint->getShader()->isOpaque()) {
|
||||
break;
|
||||
}
|
||||
if (paint->getColorFilter() &&
|
||||
if (!paint->getColorFilter() ||
|
||||
((paint->getColorFilter()->getFlags() &
|
||||
SkColorFilter::kAlphaUnchanged_Flag) == 0)) {
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
case SkXfermode::kSA_Coeff:
|
||||
if (paint->getAlpha() != 0) {
|
||||
break;
|
||||
}
|
||||
if (paint->getColorFilter() &&
|
||||
((paint->getColorFilter()->getFlags() &
|
||||
SkColorFilter::kAlphaUnchanged_Flag) == 0)) {
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
case SkXfermode::kSC_Coeff:
|
||||
if (paint->getColor() != 0) { // all components must be 0
|
||||
break;
|
||||
}
|
||||
if (contentType != kNoBitmap_SkPaintBitmapOpacity || paint->getShader()) {
|
||||
break;
|
||||
}
|
||||
if (paint->getColorFilter() && (
|
||||
(paint->getColorFilter()->getFlags() &
|
||||
SkColorFilter::kAlphaUnchanged_Flag) == 0)) {
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
SkColorFilter::kAlphaUnchanged_Flag) != 0)) {
|
||||
if (0xff == paint->getAlpha() &&
|
||||
contentType != kUnknown_SkPaintBitmapOpacity &&
|
||||
(!paint->getShader() || paint->getShader()->isOpaque())) {
|
||||
opacityType = SkXfermode::kOpaque_SrcColorOpacity;
|
||||
} else if (0 == paint->getColor() &&
|
||||
contentType == kNoBitmap_SkPaintBitmapOpacity &&
|
||||
!paint->getShader()) {
|
||||
opacityType = SkXfermode::kTransparentBlack_SrcColorOpacity;
|
||||
} else if (0 == paint->getAlpha()) {
|
||||
opacityType = SkXfermode::kTransparentAlpha_SrcColorOpacity;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
return SkXfermode::IsOpaque(paint->getXfermode(), opacityType);
|
||||
}
|
||||
|
||||
bool isPaintOpaque(const SkPaint* paint, const SkBitmap* bmpReplacesShader) {
|
||||
|
@ -667,10 +667,6 @@ const ProcCoeff gProcCoeffs[] = {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool SkXfermode::asCoeff(Coeff* src, Coeff* dst) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SkXfermode::asMode(Mode* mode) const {
|
||||
return false;
|
||||
}
|
||||
@ -783,6 +779,14 @@ void SkXfermode::xferA8(SkAlpha* SK_RESTRICT dst,
|
||||
}
|
||||
}
|
||||
|
||||
bool SkXfermode::supportsCoverageAsAlpha() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SkXfermode::isOpaque(SkXfermode::SrcColorOpacity opacityType) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -805,18 +809,45 @@ bool SkProcCoeffXfermode::asMode(Mode* mode) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SkProcCoeffXfermode::asCoeff(Coeff* sc, Coeff* dc) const {
|
||||
bool SkProcCoeffXfermode::supportsCoverageAsAlpha() const {
|
||||
if (CANNOT_USE_COEFF == fSrcCoeff) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sc) {
|
||||
*sc = fSrcCoeff;
|
||||
}
|
||||
if (dc) {
|
||||
*dc = fDstCoeff;
|
||||
}
|
||||
switch (fDstCoeff) {
|
||||
case SkXfermode::kOne_Coeff:
|
||||
case SkXfermode::kISA_Coeff:
|
||||
case SkXfermode::kISC_Coeff:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool SkProcCoeffXfermode::isOpaque(SkXfermode::SrcColorOpacity opacityType) const {
|
||||
if (CANNOT_USE_COEFF == fSrcCoeff) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SkXfermode::kDA_Coeff == fSrcCoeff || SkXfermode::kDC_Coeff == fSrcCoeff ||
|
||||
SkXfermode::kIDA_Coeff == fSrcCoeff || SkXfermode::kIDC_Coeff == fSrcCoeff) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (fDstCoeff) {
|
||||
case SkXfermode::kZero_Coeff:
|
||||
return true;
|
||||
case SkXfermode::kISA_Coeff:
|
||||
return SkXfermode::kOpaque_SrcColorOpacity == opacityType;
|
||||
case SkXfermode::kSA_Coeff:
|
||||
return SkXfermode::kTransparentBlack_SrcColorOpacity == opacityType ||
|
||||
SkXfermode::kTransparentAlpha_SrcColorOpacity == opacityType;
|
||||
case SkXfermode::kSC_Coeff:
|
||||
return SkXfermode::kTransparentBlack_SrcColorOpacity == opacityType;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SkProcCoeffXfermode::xfer32(SkPMColor* SK_RESTRICT dst,
|
||||
@ -1309,13 +1340,6 @@ bool SkXfermode::AsMode(const SkXfermode* xfer, Mode* mode) {
|
||||
return xfer->asMode(mode);
|
||||
}
|
||||
|
||||
bool SkXfermode::AsCoeff(const SkXfermode* xfer, Coeff* src, Coeff* dst) {
|
||||
if (NULL == xfer) {
|
||||
return ModeAsCoeff(kSrcOver_Mode, src, dst);
|
||||
}
|
||||
return xfer->asCoeff(src, dst);
|
||||
}
|
||||
|
||||
bool SkXfermode::IsMode(const SkXfermode* xfer, Mode mode) {
|
||||
// if xfer==null then the mode is srcover
|
||||
Mode m = kSrcOver_Mode;
|
||||
@ -1325,6 +1349,24 @@ bool SkXfermode::IsMode(const SkXfermode* xfer, Mode mode) {
|
||||
return mode == m;
|
||||
}
|
||||
|
||||
bool SkXfermode::SupportsCoverageAsAlpha(const SkXfermode* xfer) {
|
||||
// if xfer is NULL we treat it as srcOver which always supports coverageAsAlpha
|
||||
if (!xfer) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return xfer->supportsCoverageAsAlpha();
|
||||
}
|
||||
|
||||
bool SkXfermode::IsOpaque(const SkXfermode* xfer, SrcColorOpacity opacityType) {
|
||||
// if xfer is NULL we treat it as srcOver which is opaque if our src is opaque
|
||||
if (!xfer) {
|
||||
return SkXfermode::kOpaque_SrcColorOpacity == opacityType;
|
||||
}
|
||||
|
||||
return xfer->isOpaque(opacityType);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//////////// 16bit xfermode procs
|
||||
|
||||
|
@ -32,7 +32,9 @@ public:
|
||||
|
||||
bool asMode(Mode* mode) const SK_OVERRIDE;
|
||||
|
||||
bool asCoeff(Coeff* sc, Coeff* dc) const SK_OVERRIDE;
|
||||
bool supportsCoverageAsAlpha() const SK_OVERRIDE;
|
||||
|
||||
bool isOpaque(SkXfermode::SrcColorOpacity opacityType) const SK_OVERRIDE;
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
virtual bool asFragmentProcessor(GrFragmentProcessor**,
|
||||
|
Loading…
Reference in New Issue
Block a user