Check XpFactory equality in DrawState
BUG=skia:
Review URL: https://codereview.chromium.org/767873006
diff --git a/include/gpu/GrXferProcessor.h b/include/gpu/GrXferProcessor.h
index ee3764d..10ecf54 100644
--- a/include/gpu/GrXferProcessor.h
+++ b/include/gpu/GrXferProcessor.h
@@ -54,7 +54,50 @@
*/
virtual bool supportsRGBCoverage(GrColor knownColor, uint32_t knownColorFlags) const = 0;
+ bool isEqual(const GrXPFactory& that) const {
+ if (this->classID() != that.classID()) {
+ return false;
+ }
+ return this->onIsEqual(that);
+ }
+
+ /**
+ * Helper for down-casting to a GrXPFactory subclass
+ */
+ template <typename T> const T& cast() const { return *static_cast<const T*>(this); }
+
+ uint32_t classID() const { SkASSERT(kIllegalXPFClassID != fClassID); return fClassID; }
+
+protected:
+ GrXPFactory() : fClassID(kIllegalXPFClassID) {}
+
+ template <typename XPF_SUBCLASS> void initClassID() {
+ static uint32_t kClassID = GenClassID();
+ fClassID = kClassID;
+ }
+
+ uint32_t fClassID;
+
private:
+ virtual bool onIsEqual(const GrXPFactory&) const = 0;
+
+ static uint32_t GenClassID() {
+ // fCurrXPFactoryID has been initialized to kIllegalXPFactoryID. The
+ // atomic inc returns the old value not the incremented value. So we add
+ // 1 to the returned value.
+ uint32_t id = static_cast<uint32_t>(sk_atomic_inc(&gCurrXPFClassID)) + 1;
+ if (!id) {
+ SkFAIL("This should never wrap as it should only be called once for each GrXPFactory "
+ "subclass.");
+ }
+ return id;
+ }
+
+ enum {
+ kIllegalXPFClassID = 0,
+ };
+ static int32_t gCurrXPFClassID;
+
typedef GrProgramElement INHERITED;
};
diff --git a/include/gpu/effects/GrPorterDuffXferProcessor.h b/include/gpu/effects/GrPorterDuffXferProcessor.h
index d1b30cc..9ff3bea 100644
--- a/include/gpu/effects/GrPorterDuffXferProcessor.h
+++ b/include/gpu/effects/GrPorterDuffXferProcessor.h
@@ -68,8 +68,12 @@
bool supportsRGBCoverage(GrColor knownColor, uint32_t knownColorFlags) const SK_OVERRIDE;
private:
- GrPorterDuffXPFactory(GrBlendCoeff src, GrBlendCoeff dst)
- : fSrc(src), fDst(dst) {}
+ GrPorterDuffXPFactory(GrBlendCoeff src, GrBlendCoeff dst);
+
+ bool onIsEqual(const GrXPFactory& xpfBase) const SK_OVERRIDE {
+ const GrPorterDuffXPFactory& xpf = xpfBase.cast<GrPorterDuffXPFactory>();
+ return (fSrc == xpf.fSrc && fDst == xpf.fDst);
+ }
GrBlendCoeff fSrc;
GrBlendCoeff fDst;
diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp
index db70bfa..8c2d75f 100644
--- a/src/gpu/GrDrawState.cpp
+++ b/src/gpu/GrDrawState.cpp
@@ -51,6 +51,10 @@
return false;
}
+ if (!this->getXPFactory()->isEqual(*that.getXPFactory())) {
+ return false;
+ }
+
for (int i = 0; i < this->numColorStages(); i++) {
if (!GrFragmentStage::AreCompatible(this->getColorStage(i), that.getColorStage(i),
explicitLocalCoords)) {
diff --git a/src/gpu/GrProcessor.cpp b/src/gpu/GrProcessor.cpp
index 810c751..96dd9ea 100644
--- a/src/gpu/GrProcessor.cpp
+++ b/src/gpu/GrProcessor.cpp
@@ -11,6 +11,7 @@
#include "GrGeometryData.h"
#include "GrInvariantOutput.h"
#include "GrMemoryPool.h"
+#include "GrXferProcessor.h"
#include "SkTLS.h"
#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
@@ -179,3 +180,10 @@
void GrGeometryData::operator delete(void* target) {
GrProcessor_Globals::GetTLS()->release(target);
}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+// Initial static variable from GrXPFactory
+int32_t GrXPFactory::gCurrXPFClassID =
+ GrXPFactory::kIllegalXPFClassID;
+
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
index 04a7b1f..55e0c93 100644
--- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
@@ -65,6 +65,11 @@
///////////////////////////////////////////////////////////////////////////////
+GrPorterDuffXPFactory::GrPorterDuffXPFactory(GrBlendCoeff src, GrBlendCoeff dst)
+ : fSrc(src), fDst(dst) {
+ this->initClassID<GrPorterDuffXPFactory>();
+}
+
GrXPFactory* GrPorterDuffXPFactory::Create(SkXfermode::Mode mode) {
switch (mode) {
case SkXfermode::kClear_Mode: {