#include "SkXfermode_opts_SSE2.h"
#include "SkXfermode_proccoeff.h"
#include "SkColorPriv.h"
+#include "SkLazyPtr.h"
#include "SkMathPriv.h"
-#include "SkOnce.h"
#include "SkReadBuffer.h"
#include "SkString.h"
#include "SkUtilsArm.h"
return false;
}
-bool SkXfermode::asNewEffect(GrEffectRef** effect, GrTexture* background) const {
+bool SkXfermode::asNewEffect(GrEffect** effect, GrTexture* background) const {
return false;
}
bool SkXfermode::AsNewEffectOrCoeff(SkXfermode* xfermode,
- GrEffectRef** effect,
+ GrEffect** effect,
Coeff* src,
Coeff* dst,
GrTexture* background) {
#include "GrEffectUnitTest.h"
#include "GrTBackendEffectFactory.h"
#include "gl/GrGLEffect.h"
+#include "gl/GrGLShaderBuilder.h"
/**
* GrEffect that implements the all the separable xfer modes that cannot be expressed as Coeffs.
return mode > SkXfermode::kLastCoeffMode && mode <= SkXfermode::kLastMode;
}
- static GrEffectRef* Create(SkXfermode::Mode mode, GrTexture* background) {
+ static GrEffect* Create(SkXfermode::Mode mode, GrTexture* background) {
if (!IsSupportedMode(mode)) {
return NULL;
} else {
- AutoEffectUnref effect(SkNEW_ARGS(XferEffect, (mode, background)));
- return CreateEffectRef(effect);
+ return SkNEW_ARGS(XferEffect, (mode, background));
}
}
}
virtual void emitCode(GrGLShaderBuilder* builder,
const GrDrawEffect& drawEffect,
- EffectKey key,
+ const GrEffectKey& key,
const char* outputColor,
const char* inputColor,
const TransformedCoordsArray& coords,
}
}
- static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+ static inline void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
+ GrEffectKeyBuilder* b) {
// The background may come from the dst or from a texture.
- int numTextures = (*drawEffect.effect())->numTextures();
- SkASSERT(numTextures <= 1);
- return (drawEffect.castEffect<XferEffect>().mode() << 1) | numTextures;
+ uint32_t key = drawEffect.effect()->numTextures();
+ SkASSERT(key <= 1);
+ key |= drawEffect.castEffect<XferEffect>().mode() << 1;
+ b->add32(key);
}
private:
};
GR_DEFINE_EFFECT_TEST(XferEffect);
-GrEffectRef* XferEffect::TestCreate(SkRandom* rand,
- GrContext*,
- const GrDrawTargetCaps&,
- GrTexture*[]) {
+GrEffect* XferEffect::TestCreate(SkRandom* rand,
+ GrContext*,
+ const GrDrawTargetCaps&,
+ GrTexture*[]) {
int mode = rand->nextRangeU(SkXfermode::kLastCoeffMode + 1, SkXfermode::kLastSeparableMode);
- AutoEffectUnref gEffect(SkNEW_ARGS(XferEffect, (static_cast<SkXfermode::Mode>(mode), NULL)));
- return CreateEffectRef(gEffect);
+ return SkNEW_ARGS(XferEffect, (static_cast<SkXfermode::Mode>(mode), NULL));
}
#endif
}
#if SK_SUPPORT_GPU
-bool SkProcCoeffXfermode::asNewEffect(GrEffectRef** effect,
- GrTexture* background) const {
+bool SkProcCoeffXfermode::asNewEffect(GrEffect** effect, GrTexture* background) const {
if (XferEffect::IsSupportedMode(fMode)) {
if (NULL != effect) {
*effect = XferEffect::Create(fMode, background);
///////////////////////////////////////////////////////////////////////////////
-SK_DECLARE_STATIC_MUTEX(gCachedXfermodesMutex);
-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);
-
- for (size_t i = 0; i < SK_ARRAY_COUNT(gCachedXfermodes); ++i) {
- SkSafeUnref(gCachedXfermodes[i]);
- gCachedXfermodes[i] = NULL;
- }
-}
-
-extern SkProcCoeffXfermode* SkPlatformXfermodeFactory(const ProcCoeff& rec,
- SkXfermode::Mode mode);
+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]);
+// Technically, can't be static and passed as a template parameter. So we use anonymous namespace.
+namespace {
+SkXfermode* create_mode(int iMode) {
+ SkXfermode::Mode mode = (SkXfermode::Mode)iMode;
ProcCoeff rec = gProcCoeffs[mode];
SkXfermodeProc pp = SkPlatformXfermodeProcFactory(mode);
break;
}
}
- gCachedXfermodes[mode] = xfer;
+ return xfer;
}
+} // namespace
+
SkXfermode* SkXfermode::Create(Mode mode) {
SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount);
- SkASSERT(SK_ARRAY_COUNT(gCachedXfermodes) == kModeCount);
if ((unsigned)mode >= kModeCount) {
// report error
return NULL;
}
- // Skia's "defaut" mode is srcover. NULL in SkPaint is interpreted as srcover
+ // Skia's "default" mode is srcover. NULL in SkPaint is interpreted as srcover
// so we can just return NULL from the factory.
if (kSrcOver_Mode == mode) {
return NULL;
}
- SkOnce(&gXfermodeCached[mode], &gCachedXfermodesMutex, create_mode, mode);
- SkXfermode* xfer = gCachedXfermodes[mode];
- SkASSERT(xfer != NULL);
- return SkSafeRef(xfer);
+ SK_DECLARE_STATIC_LAZY_PTR_ARRAY(SkXfermode, cached, kModeCount, create_mode);
+ return SkSafeRef(cached[mode]);
}
SkXfermodeProc SkXfermode::GetProc(Mode mode) {