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
This commit is contained in:
parent
5be2def19a
commit
140950cc59
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user