46fba0d793
R=robertphillips@google.com Review URL: https://codereview.appspot.com/6785049 git-svn-id: http://skia.googlecode.com/svn/trunk@6130 2bbb7eff-a529-9590-31e7-b0007b416f81
130 lines
4.3 KiB
C++
130 lines
4.3 KiB
C++
/*
|
|
* Copyright 2012 Google Inc.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#ifndef GrBackendEffectFactory_DEFINED
|
|
#define GrBackendEffectFactory_DEFINED
|
|
|
|
#include "GrTypes.h"
|
|
#include "SkTemplates.h"
|
|
#include "GrNoncopyable.h"
|
|
|
|
/** Given a GrEffect of a particular type, creates the corresponding
|
|
graphics-backend-specific GrGLEffect. Also tracks equivalence
|
|
of shaders generated via a key.
|
|
*/
|
|
|
|
class GrEffect;
|
|
class GrGLEffect;
|
|
class GrGLCaps;
|
|
|
|
class GrBackendEffectFactory : public GrNoncopyable {
|
|
public:
|
|
typedef uint32_t EffectKey;
|
|
enum {
|
|
kEffectKeyBits = 10,
|
|
/**
|
|
* Some aspects of the generated code may be determined by the particular textures that are
|
|
* associated with the effect. These manipulations are performed by GrGLShaderBuilder beyond
|
|
* GrGLEffects' control. So there is a dedicated part of the key which is combined
|
|
* automatically with the bits produced by GrGLEffect::GenKey().
|
|
*/
|
|
kTextureKeyBits = 6
|
|
};
|
|
|
|
virtual EffectKey glEffectKey(const GrEffect&, const GrGLCaps&) const = 0;
|
|
virtual GrGLEffect* createGLInstance(const GrEffect&) const = 0;
|
|
|
|
bool operator ==(const GrBackendEffectFactory& b) const {
|
|
return fEffectClassID == b.fEffectClassID;
|
|
}
|
|
bool operator !=(const GrBackendEffectFactory& b) const {
|
|
return !(*this == b);
|
|
}
|
|
|
|
virtual const char* name() const = 0;
|
|
|
|
protected:
|
|
enum {
|
|
kIllegalEffectClassID = 0,
|
|
};
|
|
|
|
GrBackendEffectFactory() {
|
|
fEffectClassID = kIllegalEffectClassID;
|
|
}
|
|
|
|
static EffectKey GenID() {
|
|
// fCurrEffectClassID has been initialized to kIllegalEffectClassID. The
|
|
// atomic inc returns the old value not the incremented value. So we add
|
|
// 1 to the returned value.
|
|
int32_t id = sk_atomic_inc(&fCurrEffectClassID) + 1;
|
|
GrAssert(id < (1 << (8 * sizeof(EffectKey) - kEffectKeyBits)));
|
|
return id;
|
|
}
|
|
|
|
EffectKey fEffectClassID;
|
|
|
|
private:
|
|
static int32_t fCurrEffectClassID;
|
|
};
|
|
|
|
template <typename EffectClass>
|
|
class GrTBackendEffectFactory : public GrBackendEffectFactory {
|
|
|
|
public:
|
|
typedef typename EffectClass::GLEffect GLEffect;
|
|
|
|
/** Returns a human-readable name that is accessible via GrEffect or
|
|
GrGLEffect and is consistent between the two of them.
|
|
*/
|
|
virtual const char* name() const SK_OVERRIDE { return EffectClass::Name(); }
|
|
|
|
/** Returns a value that identifies the GLSL shader code generated by
|
|
a GrEffect. This enables caching of generated shaders. Part of the
|
|
id identifies the GrEffect subclass. The remainder is based
|
|
on the aspects of the GrEffect object's configuration that affect
|
|
GLSL code generation. */
|
|
virtual EffectKey glEffectKey(const GrEffect& effect, const GrGLCaps& caps) const SK_OVERRIDE {
|
|
GrAssert(kIllegalEffectClassID != fEffectClassID);
|
|
EffectKey effectKey = GLEffect::GenKey(effect, caps);
|
|
EffectKey textureKey = GLEffect::GenTextureKey(effect, caps);
|
|
#if GR_DEBUG
|
|
static const EffectKey kIllegalIDMask = (uint16_t) (~((1U << kEffectKeyBits) - 1));
|
|
GrAssert(!(kIllegalIDMask & effectKey));
|
|
|
|
static const EffectKey kIllegalTextureKeyMask = (uint16_t) (~((1U << kTextureKeyBits) - 1));
|
|
GrAssert(!(kIllegalTextureKeyMask & textureKey));
|
|
#endif
|
|
return fEffectClassID | (textureKey << kEffectKeyBits) | effectKey;
|
|
}
|
|
|
|
/** Returns a new instance of the appropriate *GL* implementation class
|
|
for the given GrEffect; caller is responsible for deleting
|
|
the object. */
|
|
virtual GLEffect* createGLInstance(const GrEffect& effect) const SK_OVERRIDE {
|
|
return SkNEW_ARGS(GLEffect, (*this, effect));
|
|
}
|
|
|
|
/** This class is a singleton. This function returns the single instance.
|
|
*/
|
|
static const GrBackendEffectFactory& getInstance() {
|
|
static SkAlignedSTStorage<1, GrTBackendEffectFactory> gInstanceMem;
|
|
static const GrTBackendEffectFactory* gInstance;
|
|
if (!gInstance) {
|
|
gInstance = SkNEW_PLACEMENT(gInstanceMem.get(),
|
|
GrTBackendEffectFactory);
|
|
}
|
|
return *gInstance;
|
|
}
|
|
|
|
protected:
|
|
GrTBackendEffectFactory() {
|
|
fEffectClassID = GenID() << (kEffectKeyBits + kTextureKeyBits) ;
|
|
}
|
|
};
|
|
|
|
#endif
|