blob: d115a546474d6926bdc116615f13faa8c44a4f07 [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"
bungeman@google.comd9947f62013-12-18 15:27:39 +000013#include "SkThread.h"
commit-bot@chromium.orga0b40282013-09-18 13:00:55 +000014#include "SkTypes.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
commit-bot@chromium.orga0b40282013-09-18 13:00:55 +000031class GrBackendEffectFactory : public SkNoncopyable {
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,
bsalomon@google.com77af6802013-10-02 13:04:56 +000036 kEffectKeyBits = 10,
bsalomon@google.com46fba0d2012-10-25 21:42:05 +000037 /**
bsalomon@google.com77af6802013-10-02 13:04:56 +000038 * The framework automatically includes coord transforms and texture accesses in their
39 * effect's EffectKey, so effects don't need to account for them in GenKey().
bsalomon@google.com46fba0d2012-10-25 21:42:05 +000040 */
bsalomon@google.comb016f412013-09-30 19:57:15 +000041 kTextureKeyBits = 4,
bsalomon@google.com77af6802013-10-02 13:04:56 +000042 kTransformKeyBits = 6,
43 kAttribKeyBits = 6,
44 kClassIDBits = 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.com77af6802013-10-02 13:04:56 +000059 static EffectKey GetTransformKey(EffectKey key) {
60 return key >> (kEffectKeyBits + kTextureKeyBits) & ((1U << kTransformKeyBits) - 1);
61 }
62
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000063protected:
64 enum {
bsalomon@google.com021fc732012-10-25 12:47:42 +000065 kIllegalEffectClassID = 0,
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000066 };
67
bsalomon@google.com396e61f2012-10-25 19:00:29 +000068 GrBackendEffectFactory() {
bsalomon@google.com021fc732012-10-25 12:47:42 +000069 fEffectClassID = kIllegalEffectClassID;
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000070 }
djsollen@google.comade109f2013-01-04 15:29:06 +000071 virtual ~GrBackendEffectFactory() {}
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000072
bsalomon@google.com46fba0d2012-10-25 21:42:05 +000073 static EffectKey GenID() {
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +000074 SkDEBUGCODE(static const int32_t kClassIDBits = 8 * sizeof(EffectKey) -
robertphillips@google.comad9327f2013-03-26 19:35:06 +000075 kTextureKeyBits - kEffectKeyBits - kAttribKeyBits);
bsalomon@google.com021fc732012-10-25 12:47:42 +000076 // fCurrEffectClassID has been initialized to kIllegalEffectClassID. The
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000077 // atomic inc returns the old value not the incremented value. So we add
78 // 1 to the returned value.
bsalomon@google.com021fc732012-10-25 12:47:42 +000079 int32_t id = sk_atomic_inc(&fCurrEffectClassID) + 1;
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000080 SkASSERT(id < (1 << kClassIDBits));
bsalomon@google.comb4a55b72012-11-02 20:45:37 +000081 return static_cast<EffectKey>(id);
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000082 }
83
bsalomon@google.com46fba0d2012-10-25 21:42:05 +000084 EffectKey fEffectClassID;
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000085
86private:
bsalomon@google.com021fc732012-10-25 12:47:42 +000087 static int32_t fCurrEffectClassID;
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000088};
89
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000090#endif