1ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com/*
2ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com * Copyright 2012 Google Inc.
3ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com *
4ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com * Use of this source code is governed by a BSD-style license that can be
5ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com * found in the LICENSE file.
6ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com */
7ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com
8b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#ifndef GrBackendProcessorFactory_DEFINED
9b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#define GrBackendProcessorFactory_DEFINED
10ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com
11ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com#include "GrTypes.h"
128e520fc2494be84bf0d0b55143eb1d459a352a7bbsalomon@google.com#include "SkTemplates.h"
1386b0de4745a8a8317b54f23878498633b9210a8fcommit-bot@chromium.org#include "SkThread.h"
14a0b40280a49a8a43af7929ead3b3489951c58501commit-bot@chromium.org#include "SkTypes.h"
15848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon#include "SkTArray.h"
16ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com
17b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrGLProcessor;
18a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.comclass GrGLCaps;
19b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrProcessor;
20ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com
21848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon/**
22b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * Used by effects to build their keys. It incorporates each per-processor key into a larger shader
23b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt *  key.
24848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon */
25b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrProcessorKeyBuilder {
26848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomonpublic:
27b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GrProcessorKeyBuilder(SkTArray<unsigned char, true>* data) : fData(data), fCount(0) {
28848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon        SkASSERT(0 == fData->count() % sizeof(uint32_t));
29848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon    }
30848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon
31848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon    void add32(uint32_t v) {
32848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon        ++fCount;
33848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon        fData->push_back_n(4, reinterpret_cast<uint8_t*>(&v));
34848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon    }
35848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon
36929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon    /** Inserts count uint32_ts into the key. The returned pointer is only valid until the next
37929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon        add*() call. */
38929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon    uint32_t* SK_WARN_UNUSED_RESULT add32n(int count) {
39929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon        SkASSERT(count > 0);
40929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon        fCount += count;
41929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon        return reinterpret_cast<uint32_t*>(fData->push_back_n(4 * count));
42929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon    }
43929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon
44848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon    size_t size() const { return sizeof(uint32_t) * fCount; }
45848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon
46848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomonprivate:
47848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon    SkTArray<uint8_t, true>* fData; // unowned ptr to the larger key.
48848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon    int fCount;                     // number of uint32_ts added to fData by the effect.
49848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon};
50848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon
51929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon/**
52b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * This class is used to pass the key that was created for a GrGLProcessor back to it
5363e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon * when it emits code. It may allow the emit step to skip calculations that were
5463e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon * performed when computing the key.
5563e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon */
56b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrProcessorKey {
5763e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomonpublic:
58b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GrProcessorKey(const uint32_t* key, int count) : fKey(key), fCount(count) {
5963e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon        SkASSERT(0 == reinterpret_cast<intptr_t>(key) % sizeof(uint32_t));
6063e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    }
6163e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon
6263e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    /** Gets the uint32_t values that the effect inserted into the key. */
6363e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    uint32_t get32(int index) const {
6463e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon        SkASSERT(index >=0 && index < fCount);
6563e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon        return fKey[index];
6663e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    }
6763e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon
6863e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    /** Gets the number of uint32_t values that the effect inserted into the key. */
6963e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    int count32() const { return fCount; }
7063e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon
7163e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomonprivate:
7263e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    const uint32_t* fKey;           // unowned ptr into the larger key.
7363e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    int             fCount;         // number of uint32_ts inserted by the effect into its key.
7463e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon};
7563e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon
7663e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon/**
77b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * Given a GrProcessor of a particular type, creates the corresponding graphics-backend-specific
78929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon * effect object. It also tracks equivalence of shaders generated via a key. The factory for an
79b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * effect is accessed via GrProcessor::getFactory(). Each factory instance is assigned an ID at
80b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * construction. The ID of GrProcessor::getFactory() is used as a type identifier. Thus, a
81b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * GrProcessor subclass must always return the same object from getFactory() and that factory object
82b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * must be unique to the GrProcessor subclass (and unique from any further derived subclasses).
83929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon *
84b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * Rather than subclassing this class themselves, it is recommended that GrProcessor authors use
85929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon * the templated subclass GrTBackendEffectFactory by writing their getFactory() method as:
86929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon *
87929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon * const GrBackendEffectFactory& MyEffect::getFactory() const {
88929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon *     return GrTBackendEffectFactory<MyEffect>::getInstance();
89929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon * }
90929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon *
91929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon * Using GrTBackendEffectFactory places a few constraints on the effect. See that class's comments.
92929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon */
93b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrBackendProcessorFactory : SkNoncopyable {
94ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.compublic:
95929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon    /**
96b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt     * Generates an effect's key. The key is based on the aspects of the GrProcessor object's
97b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt     * configuration that affect GLSL code generation. Two GrProcessor instances that would cause
98929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon     * this->createGLInstance()->emitCode() to produce different code must produce different keys.
99929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon     */
100b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual void getGLProcessorKey(const GrProcessor&, const GrGLCaps&,
101b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                   GrProcessorKeyBuilder*) const = 0;
102ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com
103929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon    /**
104929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon     * Produces a human-reable name for the effect.
105929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon     */
1067940100faec0b758645d40c876e9c796884410f7mtklein    virtual const char* name() const = 0;
107c0ea398aff8254e31152cbb94c9ab6150428e252bsalomon
108929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon    /**
109929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon     * A unique value for every instance of this factory. It is automatically incorporated into the
110b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt     * effect's key. This allows keys generated by getGLProcessorKey() to only be unique within a
111b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt     * GrProcessor subclass and not necessarily across subclasses.
112929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon     */
113929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon    uint32_t effectClassID() const { return fEffectClassID; }
114929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon
115ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.comprotected:
116b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GrBackendProcessorFactory() : fEffectClassID(GenID()) {}
117b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual ~GrBackendProcessorFactory() {}
118929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon
119929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomonprivate:
120ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com    enum {
121021fc736f89fddac4f26b3f32f50263ff8fe3279bsalomon@google.com        kIllegalEffectClassID = 0,
122ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com    };
123ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com
124929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon    static uint32_t GenID() {
125021fc736f89fddac4f26b3f32f50263ff8fe3279bsalomon@google.com        // fCurrEffectClassID has been initialized to kIllegalEffectClassID. The
126ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com        // atomic inc returns the old value not the incremented value. So we add
127ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com        // 1 to the returned value.
128929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon        uint32_t id = static_cast<uint32_t>(sk_atomic_inc(&fCurrEffectClassID)) + 1;
129929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon        if (!id) {
130b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt            SkFAIL("This should never wrap as it should only be called once for each GrProcessor "
131929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon                   "subclass.");
132929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon        }
133848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon        return id;
134ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com    }
135ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com
136929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon    const uint32_t fEffectClassID;
137021fc736f89fddac4f26b3f32f50263ff8fe3279bsalomon@google.com    static int32_t fCurrEffectClassID;
138ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com};
139ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com
140b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrFragmentProcessor;
141b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrGeometryProcessor;
142b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrGLFragmentProcessor;
143b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrGLGeometryProcessor;
144b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt
145b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt/**
146b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * Backend processor factory cannot actually create anything, it is up to subclasses to implement
147b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * a create binding which matches Gr to GL in a type safe way
148b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt */
149b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt
150b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrBackendFragmentProcessorFactory : public GrBackendProcessorFactory {
151b0a8a377f832c59cee939ad721e1f87d378b7142joshualittpublic:
152b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    /**
153b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt     * Creates a GrGLProcessor instance that is used both to generate code for the GrProcessor in a
154b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt     * GLSL program and to manage updating uniforms for the program when it is used.
155b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt     */
156b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual GrGLFragmentProcessor* createGLInstance(const GrFragmentProcessor&) const = 0;
157b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt};
158b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt
159b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrBackendGeometryProcessorFactory : public GrBackendProcessorFactory {
160b0a8a377f832c59cee939ad721e1f87d378b7142joshualittpublic:
161b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    /**
162b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt     * Creates a GrGLProcessor instance that is used both to generate code for the GrProcessor in a
163b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt     * GLSL program and to manage updating uniforms for the program when it is used.
164b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt     */
165b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual GrGLGeometryProcessor* createGLInstance(const GrGeometryProcessor&) const = 0;
166b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt};
167b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt
168ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com#endif
169