diff options
author | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-03-28 20:04:11 +0000 |
---|---|---|
committer | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-03-28 20:04:11 +0000 |
commit | 140950cc595a3058144681b088e44ff1f8f52d5b (patch) | |
tree | 71f2c9a9feb906b25f4a925b4b8dc7685bf30575 | |
parent | 5be2def19a5f91497d1e4b98c5e383dd36c1ecab (diff) |
SkOnce for SkXfermode::Create(Mode)
This removes the mutex from the fast path when we've already cached it.
BUG=skia:
R=reed@google.com, bungeman@google.com, mtklein@google.com
Author: mtklein@chromium.org
Review URL: https://codereview.chromium.org/215533002
git-svn-id: http://skia.googlecode.com/svn/trunk@13986 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | src/core/SkXfermode.cpp | 98 |
1 files changed, 51 insertions, 47 deletions
diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp index 9b66a66f17..674078ef3a 100644 --- a/src/core/SkXfermode.cpp +++ b/src/core/SkXfermode.cpp @@ -10,11 +10,12 @@ #include "SkXfermode.h" #include "SkXfermode_proccoeff.h" #include "SkColorPriv.h" -#include "SkReadBuffer.h" -#include "SkWriteBuffer.h" #include "SkMathPriv.h" +#include "SkOnce.h" +#include "SkReadBuffer.h" #include "SkString.h" #include "SkUtilsArm.h" +#include "SkWriteBuffer.h" #if !SK_ARM_NEON_IS_NONE #include "SkXfermode_opts_arm_neon.h" @@ -1671,7 +1672,8 @@ void SkDstOutXfermode::toString(SkString* str) const { /////////////////////////////////////////////////////////////////////////////// SK_DECLARE_STATIC_MUTEX(gCachedXfermodesMutex); -static SkXfermode* gCachedXfermodes[SkXfermode::kLastMode + 1]; +static SkXfermode* gCachedXfermodes[SkXfermode::kLastMode + 1]; // All NULL to start. +static bool gXfermodeCached[SK_ARRAY_COUNT(gCachedXfermodes)]; // All false to start. void SkXfermode::Term() { SkAutoMutexAcquire ac(gCachedXfermodesMutex); @@ -1686,6 +1688,50 @@ extern SkProcCoeffXfermode* SkPlatformXfermodeFactory(const ProcCoeff& rec, SkXfermode::Mode mode); extern SkXfermodeProc SkPlatformXfermodeProcFactory(SkXfermode::Mode mode); + +static void create_mode(SkXfermode::Mode mode) { + SkASSERT(NULL == gCachedXfermodes[mode]); + + ProcCoeff rec = gProcCoeffs[mode]; + SkXfermodeProc pp = SkPlatformXfermodeProcFactory(mode); + if (pp != NULL) { + rec.fProc = pp; + } + + SkXfermode* xfer = NULL; + // 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 SkXfermode::kClear_Mode: + xfer = SkClearXfermode::Create(rec); + break; + case SkXfermode::kSrc_Mode: + xfer = SkSrcXfermode::Create(rec); + break; + case SkXfermode::kSrcOver_Mode: + SkASSERT(false); // should not land here + break; + case SkXfermode::kDstIn_Mode: + xfer = SkDstInXfermode::Create(rec); + break; + case SkXfermode::kDstOut_Mode: + xfer = SkDstOutXfermode::Create(rec); + break; + default: + // no special-case, just rely in the rec and its function-ptrs + xfer = SkProcCoeffXfermode::Create(rec, mode); + break; + } + } + gCachedXfermodes[mode] = xfer; +} + SkXfermode* SkXfermode::Create(Mode mode) { SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); SkASSERT(SK_ARRAY_COUNT(gCachedXfermodes) == kModeCount); @@ -1701,51 +1747,9 @@ SkXfermode* SkXfermode::Create(Mode mode) { return NULL; } - // guard our access to gCachedXfermodes, since we may write into it - SkAutoMutexAcquire ac(gCachedXfermodesMutex); - + SkOnce(&gXfermodeCached[mode], &gCachedXfermodesMutex, create_mode, mode); SkXfermode* xfer = gCachedXfermodes[mode]; - if (NULL == xfer) { - ProcCoeff rec = gProcCoeffs[mode]; - - SkXfermodeProc pp = SkPlatformXfermodeProcFactory(mode); - - if (pp != NULL) { - rec.fProc = pp; - } - - // 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 = SkClearXfermode::Create(rec); - break; - case kSrc_Mode: - xfer = SkSrcXfermode::Create(rec); - break; - case kSrcOver_Mode: - SkASSERT(false); // should not land here - break; - case kDstIn_Mode: - xfer = SkDstInXfermode::Create(rec); - break; - case kDstOut_Mode: - xfer = SkDstOutXfermode::Create(rec); - break; - default: - // no special-case, just rely in the rec and its function-ptrs - xfer = SkProcCoeffXfermode::Create(rec, mode); - break; - } - } - gCachedXfermodes[mode] = xfer; - } + SkASSERT(xfer != NULL); return SkSafeRef(xfer); } |