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