diff options
Diffstat (limited to 'src/core/SkXfermode.cpp')
-rw-r--r-- | src/core/SkXfermode.cpp | 168 |
1 files changed, 69 insertions, 99 deletions
diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp index 8c6eb2ca68..6f2fee6913 100644 --- a/src/core/SkXfermode.cpp +++ b/src/core/SkXfermode.cpp @@ -8,6 +8,7 @@ #include "SkXfermode.h" +#include "SkXfermode_proccoeff.h" #include "SkColorPriv.h" #include "SkFlattenableBuffers.h" #include "SkMathPriv.h" @@ -624,16 +625,7 @@ static SkPMColor luminosity_modeproc(SkPMColor src, SkPMColor dst) { return SkPackARGB32(a, r, g, b); } - -struct ProcCoeff { - SkXfermodeProc fProc; - SkXfermode::Coeff fSC; - SkXfermode::Coeff fDC; -}; - -#define CANNOT_USE_COEFF SkXfermode::Coeff(-1) - -static const ProcCoeff gProcCoeffs[] = { +const ProcCoeff gProcCoeffs[] = { { clear_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kZero_Coeff }, { src_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kZero_Coeff }, { dst_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kOne_Coeff }, @@ -1345,83 +1337,51 @@ GrEffectRef* XferEffect::TestCreate(SkRandom* rand, /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// -class SkProcCoeffXfermode : public SkProcXfermode { -public: - SkProcCoeffXfermode(const ProcCoeff& rec, Mode mode) - : INHERITED(rec.fProc) { - fMode = mode; - // these may be valid, or may be CANNOT_USE_COEFF - fSrcCoeff = rec.fSC; - fDstCoeff = rec.fDC; +bool SkProcCoeffXfermode::asMode(Mode* mode) const { + if (mode) { + *mode = fMode; } + return true; +} - virtual bool asMode(Mode* mode) const SK_OVERRIDE { - if (mode) { - *mode = fMode; - } - return true; +bool SkProcCoeffXfermode::asCoeff(Coeff* sc, Coeff* dc) const { + if (CANNOT_USE_COEFF == fSrcCoeff) { + return false; } - virtual bool asCoeff(Coeff* sc, Coeff* dc) const SK_OVERRIDE { - if (CANNOT_USE_COEFF == fSrcCoeff) { - return false; - } - - if (sc) { - *sc = fSrcCoeff; - } - if (dc) { - *dc = fDstCoeff; - } - return true; + if (sc) { + *sc = fSrcCoeff; + } + if (dc) { + *dc = fDstCoeff; } + return true; +} #if SK_SUPPORT_GPU - virtual bool asNewEffectOrCoeff(GrContext*, - GrEffectRef** effect, - Coeff* src, - Coeff* dst, - GrTexture* background) const SK_OVERRIDE { - if (this->asCoeff(src, dst)) { - return true; - } - if (XferEffect::IsSupportedMode(fMode)) { - if (NULL != effect) { - *effect = XferEffect::Create(fMode, background); - SkASSERT(NULL != *effect); - } - return true; +bool SkProcCoeffXfermode::asNewEffectOrCoeff(GrContext*, + GrEffectRef** effect, + Coeff* src, + Coeff* dst, + GrTexture* background) const { + if (this->asCoeff(src, dst)) { + return true; + } + if (XferEffect::IsSupportedMode(fMode)) { + if (NULL != effect) { + *effect = XferEffect::Create(fMode, background); + SkASSERT(NULL != *effect); } - return false; + return true; } + return false; +} #endif - SK_DEVELOPER_TO_STRING() - SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkProcCoeffXfermode) - -protected: - SkProcCoeffXfermode(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) { - fMode = (SkXfermode::Mode)buffer.read32(); - - const ProcCoeff& rec = gProcCoeffs[fMode]; - // these may be valid, or may be CANNOT_USE_COEFF - fSrcCoeff = rec.fSC; - fDstCoeff = rec.fDC; - // now update our function-ptr in the super class - this->INHERITED::setProc(rec.fProc); - } - - virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE { - this->INHERITED::flatten(buffer); - buffer.write32(fMode); - } - -private: - Mode fMode; - Coeff fSrcCoeff, fDstCoeff; - - typedef SkProcXfermode INHERITED; -}; +void SkProcCoeffXfermode::flatten(SkFlattenableWriteBuffer& buffer) const { + this->INHERITED::flatten(buffer); + buffer.write32(fMode); +} const char* SkXfermode::ModeName(Mode mode) { SkASSERT((unsigned) mode <= (unsigned)kLastMode); @@ -1693,6 +1653,9 @@ void SkXfermode::Term() { } } +extern SkProcCoeffXfermode* SkPlatformXfermodeFactory(const ProcCoeff& rec, + SkXfermode::Mode mode); + SkXfermode* SkXfermode::Create(Mode mode) { SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); SkASSERT(SK_ARRAY_COUNT(gCachedXfermodes) == kModeCount); @@ -1714,29 +1677,36 @@ SkXfermode* SkXfermode::Create(Mode mode) { SkXfermode* xfer = gCachedXfermodes[mode]; if (NULL == xfer) { const ProcCoeff& rec = gProcCoeffs[mode]; - // All modes can in theory be represented by the ProcCoeff rec, since - // it contains function ptrs. However, a few modes are both simple and - // commonly used, so we call those out for their own subclasses here. - switch (mode) { - case kClear_Mode: - xfer = SkNEW_ARGS(SkClearXfermode, (rec)); - break; - case kSrc_Mode: - xfer = SkNEW_ARGS(SkSrcXfermode, (rec)); - break; - case kSrcOver_Mode: - SkASSERT(false); // should not land here - break; - case kDstIn_Mode: - xfer = SkNEW_ARGS(SkDstInXfermode, (rec)); - break; - case kDstOut_Mode: - xfer = SkNEW_ARGS(SkDstOutXfermode, (rec)); - break; - default: - // no special-case, just rely in the rec and its function-ptrs - xfer = SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode)); - break; + + // check if we have a platform optim for that + SkProcCoeffXfermode* xfm = SkPlatformXfermodeFactory(rec, mode); + if (xfm != NULL) { + xfer = xfm; + } else { + // All modes can in theory be represented by the ProcCoeff rec, since + // it contains function ptrs. However, a few modes are both simple and + // commonly used, so we call those out for their own subclasses here. + switch (mode) { + case kClear_Mode: + xfer = SkNEW_ARGS(SkClearXfermode, (rec)); + break; + case kSrc_Mode: + xfer = SkNEW_ARGS(SkSrcXfermode, (rec)); + break; + case kSrcOver_Mode: + SkASSERT(false); // should not land here + break; + case kDstIn_Mode: + xfer = SkNEW_ARGS(SkDstInXfermode, (rec)); + break; + case kDstOut_Mode: + xfer = SkNEW_ARGS(SkDstOutXfermode, (rec)); + break; + default: + // no special-case, just rely in the rec and its function-ptrs + xfer = SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode)); + break; + } } gCachedXfermodes[mode] = xfer; } |