1/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef GrTBackendProcessorFactory_DEFINED
9#define GrTBackendProcessorFactory_DEFINED
10
11#include "GrBackendProcessorFactory.h"
12#include "gl/GrGLProgramEffects.h"
13
14/**
15 * Implements GrBackendEffectFactory for a GrProcessor subclass as a singleton. This can be used by
16 * most GrProcessor subclasses to implement the GrProcessor::getFactory() method:
17 *
18 * const GrBackendEffectFactory& MyEffect::getFactory() const {
19 *     return GrTBackendEffectFactory<MyEffect>::getInstance();
20 * }
21 *
22 * Using this class requires that the GrProcessor subclass always produces the same GrGLProcessor
23 * subclass. Additionally, it adds the following requirements to the GrProcessor and GrGLProcessor
24 * subclasses:
25 *
26 * 1. The GrGLProcessor used by GrProcessor subclass MyEffect must be named or typedef'ed to
27 *    MyEffect::GLProcessor.
28 * 2. MyEffect::GLProcessor must have a static function:
29 *      EffectKey GenKey(const GrProcessor, const GrGLCaps&)
30 *    which generates a key that maps 1 to 1 with code variations emitted by
31 *    MyEffect::GLProcessor::emitCode().
32 * 3. MyEffect must have a static function:
33 *      const char* Name()
34 *    which returns a human-readable name for the effect.
35 */
36template <class ProcessorClass, class BackEnd, class ProcessorBase, class GLProcessorBase>
37class GrTBackendProcessorFactory : public BackEnd {
38public:
39    typedef typename ProcessorClass::GLProcessor GLProcessor;
40
41    /** Returns a human-readable name for the effect. Implemented using GLProcessor::Name as
42     *  described in this class's comment. */
43    virtual const char* name() const SK_OVERRIDE { return ProcessorClass::Name(); }
44
45
46    /** Implemented using GLProcessor::GenKey as described in this class's comment. */
47    virtual void getGLProcessorKey(const GrProcessor& effect,
48                                   const GrGLCaps& caps,
49                                   GrProcessorKeyBuilder* b) const SK_OVERRIDE {
50        GLProcessor::GenKey(effect, caps, b);
51    }
52
53    /** Returns a new instance of the appropriate *GL* implementation class
54        for the given GrProcessor; caller is responsible for deleting
55        the object. */
56    virtual GLProcessorBase* createGLInstance(const ProcessorBase& effect) const SK_OVERRIDE {
57        return SkNEW_ARGS(GLProcessor, (*this, effect));
58    }
59
60    /** This class is a singleton. This function returns the single instance. */
61    static const BackEnd& getInstance() {
62        static SkAlignedSTStorage<1, GrTBackendProcessorFactory> gInstanceMem;
63        static const GrTBackendProcessorFactory* gInstance;
64        if (!gInstance) {
65            gInstance = SkNEW_PLACEMENT(gInstanceMem.get(),
66                                        GrTBackendProcessorFactory);
67        }
68        return *gInstance;
69    }
70
71protected:
72    GrTBackendProcessorFactory() {}
73};
74
75/*
76 * Every effect so far derives from one of the following subclasses of GrTBackendProcessorFactory.
77 * All of this machinery is necessary to ensure that creatGLInstace is typesafe and does not
78 * require any casting
79 */
80template <class ProcessorClass>
81class GrTBackendGeometryProcessorFactory
82        : public GrTBackendProcessorFactory<ProcessorClass,
83                                            GrBackendGeometryProcessorFactory,
84                                            GrGeometryProcessor,
85                                            GrGLGeometryProcessor> {
86protected:
87    GrTBackendGeometryProcessorFactory() {}
88};
89
90template <class ProcessorClass>
91class GrTBackendFragmentProcessorFactory
92        : public GrTBackendProcessorFactory<ProcessorClass,
93                                           GrBackendFragmentProcessorFactory,
94                                           GrFragmentProcessor,
95                                           GrGLFragmentProcessor> {
96protected:
97    GrTBackendFragmentProcessorFactory() {}
98};
99
100
101#endif
102