*/
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;
};
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;
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)) {
#include "GrGeometryData.h"
#include "GrInvariantOutput.h"
#include "GrMemoryPool.h"
+#include "GrXferProcessor.h"
#include "SkTLS.h"
#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
void GrGeometryData::operator delete(void* target) {
GrProcessor_Globals::GetTLS()->release(target);
}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+// Initial static variable from GrXPFactory
+int32_t GrXPFactory::gCurrXPFClassID =
+ GrXPFactory::kIllegalXPFClassID;
+
///////////////////////////////////////////////////////////////////////////////
+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: {