aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/gpu/GrTBackendProcessorFactory.h
blob: 78a6332d116fc09d21d710ca90a4ea5f445b2b32 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/*
 * 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 GrTBackendProcessorFactory_DEFINED
#define GrTBackendProcessorFactory_DEFINED

#include "GrBackendProcessorFactory.h"

/**
 * Implements GrBackendEffectFactory for a GrProcessor subclass as a singleton. This can be used by
 * most GrProcessor subclasses to implement the GrProcessor::getFactory() method:
 *
 * const GrBackendEffectFactory& MyEffect::getFactory() const {
 *     return GrTBackendEffectFactory<MyEffect>::getInstance();
 * }
 *
 * Using this class requires that the GrProcessor subclass always produces the same GrGLProcessor
 * subclass. Additionally, it adds the following requirements to the GrProcessor and GrGLProcessor
 * subclasses:
 *
 * 1. The GrGLProcessor used by GrProcessor subclass MyEffect must be named or typedef'ed to
 *    MyEffect::GLProcessor.
 * 2. MyEffect::GLProcessor must have a static function:
 *      EffectKey GenKey(const GrProcessor, const GrGLCaps&)
 *    which generates a key that maps 1 to 1 with code variations emitted by
 *    MyEffect::GLProcessor::emitCode().
 * 3. MyEffect must have a static function:
 *      const char* Name()
 *    which returns a human-readable name for the effect.
 */
template <class ProcessorClass, class BackEnd, class ProcessorBase, class GLProcessorBase>
class GrTBackendProcessorFactory : public BackEnd {
public:
    typedef typename ProcessorClass::GLProcessor GLProcessor;

    /** Returns a human-readable name for the effect. Implemented using GLProcessor::Name as
     *  described in this class's comment. */
    virtual const char* name() const SK_OVERRIDE { return ProcessorClass::Name(); }


    /** Implemented using GLProcessor::GenKey as described in this class's comment. */
    virtual void getGLProcessorKey(const GrProcessor& effect,
                                   const GrGLCaps& caps,
                                   GrProcessorKeyBuilder* b) const SK_OVERRIDE {
        GLProcessor::GenKey(effect, caps, b);
    }

    /** Returns a new instance of the appropriate *GL* implementation class
        for the given GrProcessor; caller is responsible for deleting
        the object. */
    virtual GLProcessorBase* createGLInstance(const ProcessorBase& effect) const SK_OVERRIDE {
        return SkNEW_ARGS(GLProcessor, (*this, effect));
    }

    /** This class is a singleton. This function returns the single instance. */
    static const BackEnd& getInstance() {
        static SkAlignedSTStorage<1, GrTBackendProcessorFactory> gInstanceMem;
        static const GrTBackendProcessorFactory* gInstance;
        if (!gInstance) {
            gInstance = SkNEW_PLACEMENT(gInstanceMem.get(),
                                        GrTBackendProcessorFactory);
        }
        return *gInstance;
    }

protected:
    GrTBackendProcessorFactory() {}
};

/*
 * Every effect so far derives from one of the following subclasses of GrTBackendProcessorFactory.
 * All of this machinery is necessary to ensure that creatGLInstace is typesafe and does not
 * require any casting
 */
template <class ProcessorClass>
class GrTBackendGeometryProcessorFactory
        : public GrTBackendProcessorFactory<ProcessorClass,
                                            GrBackendGeometryProcessorFactory,
                                            GrGeometryProcessor,
                                            GrGLGeometryProcessor> {
protected:
    GrTBackendGeometryProcessorFactory() {}
};

template <class ProcessorClass>
class GrTBackendFragmentProcessorFactory
        : public GrTBackendProcessorFactory<ProcessorClass,
                                           GrBackendFragmentProcessorFactory,
                                           GrFragmentProcessor,
                                           GrGLFragmentProcessor> {
protected:
    GrTBackendFragmentProcessorFactory() {}
};


#endif