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