Chromium Code Reviews| Index: src/core/SkXfermode.cpp |
| diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp |
| index e50e4f5ce58179cacbea609785d69a27bea8cb4f..6410d18de848b377d750a52cdb29b01184423b10 100644 |
| --- a/src/core/SkXfermode.cpp |
| +++ b/src/core/SkXfermode.cpp |
| @@ -1688,26 +1688,60 @@ void SkDstOutXfermode::toString(SkString* str) const { |
| /////////////////////////////////////////////////////////////////////////////// |
| +static SkMutex gCachedXfermodesMutex; |
|
djsollen
2013/10/04 14:48:28
use SK_DECLARE_STATIC_MUTEX
|
| +static SkXfermode* gCachedXfermodes[SkXfermode::kLastMode + 1]; |
| + |
| +void SkXfermode::Term() { |
| + SkAutoMutexAcquire ac(gCachedXfermodesMutex); |
| + |
| + for (size_t i = 0; i < SK_ARRAY_COUNT(gCachedXfermodes); ++i) { |
| + SkSafeUnref(gCachedXfermodes[i]); |
| + gCachedXfermodes[i] = NULL; |
| + } |
| +} |
| + |
| SkXfermode* SkXfermode::Create(Mode mode) { |
| SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); |
| - SkASSERT((unsigned)mode < kModeCount); |
| + SkASSERT(SK_ARRAY_COUNT(gCachedXfermodes) == kModeCount); |
| + |
| + if ((unsigned)mode >= kModeCount) { |
| + // report error |
| + return NULL; |
| + } |
| - const ProcCoeff& rec = gProcCoeffs[mode]; |
| + if (kSrcOver_Mode == mode) { |
| + return NULL; |
| + } |
| - switch (mode) { |
| - case kClear_Mode: |
| - return SkNEW_ARGS(SkClearXfermode, (rec)); |
| - case kSrc_Mode: |
| - return SkNEW_ARGS(SkSrcXfermode, (rec)); |
| - case kSrcOver_Mode: |
| - return NULL; |
| - case kDstIn_Mode: |
| - return SkNEW_ARGS(SkDstInXfermode, (rec)); |
| - case kDstOut_Mode: |
| - return SkNEW_ARGS(SkDstOutXfermode, (rec)); |
| - default: |
| - return SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode)); |
| + // guard our access to gCachedXfermodes, since we may write into it |
| + SkAutoMutexAcquire ac(gCachedXfermodesMutex); |
| + |
| + SkXfermode* xfer = gCachedXfermodes[mode]; |
| + if (NULL == xfer) { |
| + const ProcCoeff& rec = gProcCoeffs[mode]; |
| + switch (mode) { |
|
mtklein
2013/10/04 15:07:01
As someone who's not too familiar with this code,
|
| + 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: |
| + xfer = SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode)); |
| + break; |
| + } |
| + gCachedXfermodes[mode] = xfer; |
| } |
| + return SkSafeRef(xfer); |
| } |
| SkXfermodeProc SkXfermode::GetProc(Mode mode) { |