blob: 6a18169de0b3832eb76cd4aa1a32b594c08290bf [file] [log] [blame]
bsalomon@google.comae4f96a2012-05-18 19:54:48 +00001/*
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
bsalomon@google.com396e61f2012-10-25 19:00:29 +00008#ifndef GrBackendEffectFactory_DEFINED
9#define GrBackendEffectFactory_DEFINED
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000010
11#include "GrTypes.h"
bsalomon@google.com8e520fc2012-05-18 20:06:45 +000012#include "SkTemplates.h"
bsalomon@google.com2eaaefd2012-10-29 19:51:22 +000013#include "SkThread_platform.h"
senorblanco@chromium.org894790d2012-07-11 16:01:22 +000014#include "GrNoncopyable.h"
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000015
bsalomon@google.com2eaaefd2012-10-29 19:51:22 +000016/** Given a GrEffect of a particular type, creates the corresponding graphics-backend-specific
17 effect object. Also tracks equivalence of shaders generated via a key. Each factory instance
18 is assigned a generation ID at construction. The ID of the return of GrEffect::getFactory()
19 is used as a type identifier. Thus a GrEffect subclass must return a singleton from
20 getFactory(). GrEffect subclasses should use the derived class GrTBackendEffectFactory that is
21 templated on the GrEffect subclass as their factory object. It requires that the GrEffect
22 subclass has a nested class (or typedef) GLEffect which is its GL implementation and a subclass
23 of GrGLEffect.
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000024 */
25
bsalomon@google.com6340a412013-01-22 19:55:59 +000026class GrEffectRef;
bsalomon@google.comd698f772012-10-25 13:22:00 +000027class GrGLEffect;
twiz@google.coma5e65ec2012-08-02 15:15:16 +000028class GrGLCaps;
bsalomon@google.comc7818882013-03-20 19:19:53 +000029class GrDrawEffect;
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000030
bsalomon@google.com396e61f2012-10-25 19:00:29 +000031class GrBackendEffectFactory : public GrNoncopyable {
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000032public:
bsalomon@google.com46fba0d2012-10-25 21:42:05 +000033 typedef uint32_t EffectKey;
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000034 enum {
bsalomon@google.comdbe49f72012-11-05 16:36:02 +000035 kNoEffectKey = 0,
robertphillips@google.comad9327f2013-03-26 19:35:06 +000036 kEffectKeyBits = 15,
bsalomon@google.com46fba0d2012-10-25 21:42:05 +000037 /**
38 * Some aspects of the generated code may be determined by the particular textures that are
39 * associated with the effect. These manipulations are performed by GrGLShaderBuilder beyond
40 * GrGLEffects' control. So there is a dedicated part of the key which is combined
41 * automatically with the bits produced by GrGLEffect::GenKey().
42 */
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +000043 kTextureKeyBits = 6,
jvanverth@google.comc3413d62013-03-13 21:05:14 +000044 kAttribKeyBits = 6
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000045 };
46
bsalomon@google.comc7818882013-03-20 19:19:53 +000047 virtual EffectKey glEffectKey(const GrDrawEffect&, const GrGLCaps&) const = 0;
48 virtual GrGLEffect* createGLInstance(const GrDrawEffect&) const = 0;
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000049
bsalomon@google.com396e61f2012-10-25 19:00:29 +000050 bool operator ==(const GrBackendEffectFactory& b) const {
bsalomon@google.com021fc732012-10-25 12:47:42 +000051 return fEffectClassID == b.fEffectClassID;
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000052 }
bsalomon@google.com396e61f2012-10-25 19:00:29 +000053 bool operator !=(const GrBackendEffectFactory& b) const {
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000054 return !(*this == b);
55 }
56
bsalomon@google.com289efe02012-05-21 20:57:59 +000057 virtual const char* name() const = 0;
58
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000059protected:
60 enum {
bsalomon@google.com021fc732012-10-25 12:47:42 +000061 kIllegalEffectClassID = 0,
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000062 };
63
bsalomon@google.com396e61f2012-10-25 19:00:29 +000064 GrBackendEffectFactory() {
bsalomon@google.com021fc732012-10-25 12:47:42 +000065 fEffectClassID = kIllegalEffectClassID;
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000066 }
djsollen@google.comade109f2013-01-04 15:29:06 +000067 virtual ~GrBackendEffectFactory() {}
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000068
bsalomon@google.com46fba0d2012-10-25 21:42:05 +000069 static EffectKey GenID() {
robertphillips@google.com4187a2f2012-11-05 01:31:44 +000070 GR_DEBUGCODE(static const int32_t kClassIDBits = 8 * sizeof(EffectKey) -
robertphillips@google.comad9327f2013-03-26 19:35:06 +000071 kTextureKeyBits - kEffectKeyBits - kAttribKeyBits);
bsalomon@google.com021fc732012-10-25 12:47:42 +000072 // fCurrEffectClassID has been initialized to kIllegalEffectClassID. The
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000073 // atomic inc returns the old value not the incremented value. So we add
74 // 1 to the returned value.
bsalomon@google.com021fc732012-10-25 12:47:42 +000075 int32_t id = sk_atomic_inc(&fCurrEffectClassID) + 1;
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000076 SkASSERT(id < (1 << kClassIDBits));
bsalomon@google.comb4a55b72012-11-02 20:45:37 +000077 return static_cast<EffectKey>(id);
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000078 }
79
bsalomon@google.com46fba0d2012-10-25 21:42:05 +000080 EffectKey fEffectClassID;
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000081
82private:
bsalomon@google.com021fc732012-10-25 12:47:42 +000083 static int32_t fCurrEffectClassID;
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000084};
85
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000086#endif