blob: 81f908863a745cc6152b3fe8a37ad1efae5a0ab8 [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"
commit-bot@chromium.orga0b40282013-09-18 13:00:55 +000013#include "SkTypes.h"
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000014
commit-bot@chromium.orgb1aec172014-05-28 19:24:54 +000015#include "../../src/core/SkThread.h"
16
bsalomon@google.com2eaaefd2012-10-29 19:51:22 +000017/** Given a GrEffect of a particular type, creates the corresponding graphics-backend-specific
18 effect object. Also tracks equivalence of shaders generated via a key. Each factory instance
19 is assigned a generation ID at construction. The ID of the return of GrEffect::getFactory()
20 is used as a type identifier. Thus a GrEffect subclass must return a singleton from
21 getFactory(). GrEffect subclasses should use the derived class GrTBackendEffectFactory that is
22 templated on the GrEffect subclass as their factory object. It requires that the GrEffect
23 subclass has a nested class (or typedef) GLEffect which is its GL implementation and a subclass
24 of GrGLEffect.
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000025 */
26
bsalomon@google.com6340a412013-01-22 19:55:59 +000027class GrEffectRef;
bsalomon@google.comd698f772012-10-25 13:22:00 +000028class GrGLEffect;
twiz@google.coma5e65ec2012-08-02 15:15:16 +000029class GrGLCaps;
bsalomon@google.comc7818882013-03-20 19:19:53 +000030class GrDrawEffect;
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000031
commit-bot@chromium.orge3beb6b2014-04-07 19:34:38 +000032class GrBackendEffectFactory : SkNoncopyable {
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000033public:
bsalomon@google.com46fba0d2012-10-25 21:42:05 +000034 typedef uint32_t EffectKey;
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000035 enum {
bsalomon@google.comdbe49f72012-11-05 16:36:02 +000036 kNoEffectKey = 0,
bsalomon@google.com77af6802013-10-02 13:04:56 +000037 kEffectKeyBits = 10,
bsalomon@google.com46fba0d2012-10-25 21:42:05 +000038 /**
bsalomon@google.com77af6802013-10-02 13:04:56 +000039 * The framework automatically includes coord transforms and texture accesses in their
40 * effect's EffectKey, so effects don't need to account for them in GenKey().
bsalomon@google.com46fba0d2012-10-25 21:42:05 +000041 */
bsalomon@google.comb016f412013-09-30 19:57:15 +000042 kTextureKeyBits = 4,
bsalomon@google.com77af6802013-10-02 13:04:56 +000043 kTransformKeyBits = 6,
44 kAttribKeyBits = 6,
45 kClassIDBits = 6
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000046 };
47
bsalomon@google.comc7818882013-03-20 19:19:53 +000048 virtual EffectKey glEffectKey(const GrDrawEffect&, const GrGLCaps&) const = 0;
49 virtual GrGLEffect* createGLInstance(const GrDrawEffect&) const = 0;
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000050
bsalomon@google.com396e61f2012-10-25 19:00:29 +000051 bool operator ==(const GrBackendEffectFactory& b) const {
bsalomon@google.com021fc732012-10-25 12:47:42 +000052 return fEffectClassID == b.fEffectClassID;
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000053 }
bsalomon@google.com396e61f2012-10-25 19:00:29 +000054 bool operator !=(const GrBackendEffectFactory& b) const {
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000055 return !(*this == b);
56 }
57
bsalomon@google.com289efe02012-05-21 20:57:59 +000058 virtual const char* name() const = 0;
59
bsalomon@google.com77af6802013-10-02 13:04:56 +000060 static EffectKey GetTransformKey(EffectKey key) {
61 return key >> (kEffectKeyBits + kTextureKeyBits) & ((1U << kTransformKeyBits) - 1);
62 }
63
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000064protected:
65 enum {
bsalomon@google.com021fc732012-10-25 12:47:42 +000066 kIllegalEffectClassID = 0,
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000067 };
68
bsalomon@google.com396e61f2012-10-25 19:00:29 +000069 GrBackendEffectFactory() {
bsalomon@google.com021fc732012-10-25 12:47:42 +000070 fEffectClassID = kIllegalEffectClassID;
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000071 }
djsollen@google.comade109f2013-01-04 15:29:06 +000072 virtual ~GrBackendEffectFactory() {}
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000073
bsalomon@google.com46fba0d2012-10-25 21:42:05 +000074 static EffectKey GenID() {
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +000075 SkDEBUGCODE(static const int32_t kClassIDBits = 8 * sizeof(EffectKey) -
robertphillips@google.comad9327f2013-03-26 19:35:06 +000076 kTextureKeyBits - kEffectKeyBits - kAttribKeyBits);
bsalomon@google.com021fc732012-10-25 12:47:42 +000077 // fCurrEffectClassID has been initialized to kIllegalEffectClassID. The
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000078 // atomic inc returns the old value not the incremented value. So we add
79 // 1 to the returned value.
bsalomon@google.com021fc732012-10-25 12:47:42 +000080 int32_t id = sk_atomic_inc(&fCurrEffectClassID) + 1;
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000081 SkASSERT(id < (1 << kClassIDBits));
bsalomon@google.comb4a55b72012-11-02 20:45:37 +000082 return static_cast<EffectKey>(id);
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000083 }
84
bsalomon@google.com46fba0d2012-10-25 21:42:05 +000085 EffectKey fEffectClassID;
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000086
87private:
bsalomon@google.com021fc732012-10-25 12:47:42 +000088 static int32_t fCurrEffectClassID;
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000089};
90
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000091#endif