1363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger/*
2363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * Copyright 2012 Google Inc.
3363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger *
4363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * Use of this source code is governed by a BSD-style license that can be
5363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * found in the LICENSE file.
6363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger */
7363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
8363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#ifndef GrTBackendEffectFactory_DEFINED
9363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#define GrTBackendEffectFactory_DEFINED
10363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
11363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "GrBackendEffectFactory.h"
12e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger#include "GrDrawEffect.h"
13363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
14363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger/**
15363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * Implements GrBackendEffectFactory for a GrEffect subclass as a singleton.
16363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger */
17363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergertemplate <typename EffectClass>
18363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerclass GrTBackendEffectFactory : public GrBackendEffectFactory {
19363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
20363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerpublic:
21363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    typedef typename EffectClass::GLEffect GLEffect;
22363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
23363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    /** Returns a human-readable name that is accessible via GrEffect or
24363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        GrGLEffect and is consistent between the two of them.
25363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger     */
26363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    virtual const char* name() const SK_OVERRIDE { return EffectClass::Name(); }
27363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
28363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    /** Returns a value that identifies the GLSL shader code generated by
29363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        a GrEffect. This enables caching of generated shaders. Part of the
30363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        id identifies the GrEffect subclass. The remainder is based
31363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        on the aspects of the GrEffect object's configuration that affect
32363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        GLSL code generation. */
33e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    virtual EffectKey glEffectKey(const GrDrawEffect& drawEffect,
34363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                  const GrGLCaps& caps) const SK_OVERRIDE {
35363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        GrAssert(kIllegalEffectClassID != fEffectClassID);
36e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger        EffectKey effectKey = GLEffect::GenKey(drawEffect, caps);
37e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger        EffectKey textureKey = GLEffect::GenTextureKey(drawEffect, caps);
38e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger        EffectKey attribKey = GLEffect::GenAttribKey(drawEffect);
39363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#if GR_DEBUG
40363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        static const EffectKey kIllegalIDMask = (uint16_t) (~((1U << kEffectKeyBits) - 1));
41363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        GrAssert(!(kIllegalIDMask & effectKey));
42363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
43363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        static const EffectKey kIllegalTextureKeyMask = (uint16_t) (~((1U << kTextureKeyBits) - 1));
44363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        GrAssert(!(kIllegalTextureKeyMask & textureKey));
45096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
46096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        static const EffectKey kIllegalAttribKeyMask = (uint16_t) (~((1U << kAttribKeyBits) - 1));
47096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        GrAssert(!(kIllegalAttribKeyMask & textureKey));
48363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#endif
49096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        return fEffectClassID | (attribKey << (kEffectKeyBits+kTextureKeyBits)) |
50096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger               (textureKey << kEffectKeyBits) | effectKey;
51363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    }
52363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
53363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    /** Returns a new instance of the appropriate *GL* implementation class
54363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        for the given GrEffect; caller is responsible for deleting
55363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        the object. */
56e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    virtual GLEffect* createGLInstance(const GrDrawEffect& drawEffect) const SK_OVERRIDE {
57e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger        return SkNEW_ARGS(GLEffect, (*this, drawEffect));
58363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    }
59363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
60363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    /** This class is a singleton. This function returns the single instance.
61363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger     */
62363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    static const GrBackendEffectFactory& getInstance() {
63363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        static SkAlignedSTStorage<1, GrTBackendEffectFactory> gInstanceMem;
64363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        static const GrTBackendEffectFactory* gInstance;
65363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        if (!gInstance) {
66363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            gInstance = SkNEW_PLACEMENT(gInstanceMem.get(),
67363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                        GrTBackendEffectFactory);
68363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        }
69363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        return *gInstance;
70363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    }
71363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
72363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerprotected:
73363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    GrTBackendEffectFactory() {
747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fEffectClassID = GenID() << (kAttribKeyBits + kEffectKeyBits + kTextureKeyBits) ;
75363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    }
76363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger};
77363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
78363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#endif
79