/*
 * 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 "SkThread_platform.h"
#include "SkTypes.h"

/** Given a GrEffect of a particular type, creates the corresponding graphics-backend-specific
    effect object. Also tracks equivalence of shaders generated via a key. Each factory instance
    is assigned a generation ID at construction. The ID of the return of GrEffect::getFactory()
    is used as a type identifier. Thus a GrEffect subclass must return a singleton from
    getFactory(). GrEffect subclasses should use the derived class GrTBackendEffectFactory that is
    templated on the GrEffect subclass as their factory object. It requires that the GrEffect
    subclass has a nested class (or typedef) GLEffect which is its GL implementation and a subclass
    of GrGLEffect.
 */

class GrEffectRef;
class GrGLEffect;
class GrGLCaps;
class GrDrawEffect;

class GrBackendEffectFactory : public SkNoncopyable {
public:
    typedef uint32_t EffectKey;
    enum {
        kNoEffectKey = 0,
        kEffectKeyBits = 10,
        /**
         * The framework automatically includes coord transforms and texture accesses in their
         * effect's EffectKey, so effects don't need to account for them in GenKey().
         */
        kTextureKeyBits = 4,
        kTransformKeyBits = 6,
        kAttribKeyBits = 6,
        kClassIDBits = 6
    };

    virtual EffectKey glEffectKey(const GrDrawEffect&, const GrGLCaps&) const = 0;
    virtual GrGLEffect* createGLInstance(const GrDrawEffect&) 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;

    static EffectKey GetTransformKey(EffectKey key) {
        return key >> (kEffectKeyBits + kTextureKeyBits) & ((1U << kTransformKeyBits) - 1);
    }

protected:
    enum {
        kIllegalEffectClassID = 0,
    };

    GrBackendEffectFactory() {
        fEffectClassID = kIllegalEffectClassID;
    }
    virtual ~GrBackendEffectFactory() {}

    static EffectKey GenID() {
        SkDEBUGCODE(static const int32_t kClassIDBits = 8 * sizeof(EffectKey) -
                           kTextureKeyBits - kEffectKeyBits - kAttribKeyBits);
        // 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;
        SkASSERT(id < (1 << kClassIDBits));
        return static_cast<EffectKey>(id);
    }

    EffectKey fEffectClassID;

private:
    static int32_t fCurrEffectClassID;
};

#endif
