blob: 2bfefb93eee9c9c4d6289eee990e3ad52780bd85 [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.coma469c282012-10-24 18:28:34 +000026class GrEffect;
bsalomon@google.com2eaaefd2012-10-29 19:51:22 +000027class GrEffectStage;
bsalomon@google.comd698f772012-10-25 13:22:00 +000028class GrGLEffect;
twiz@google.coma5e65ec2012-08-02 15:15:16 +000029class GrGLCaps;
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,
bsalomon@google.comb4a55b72012-11-02 20:45:37 +000036 kEffectKeyBits = 12,
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 */
43 kTextureKeyBits = 6
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000044 };
45
bsalomon@google.com2eaaefd2012-10-29 19:51:22 +000046 virtual EffectKey glEffectKey(const GrEffectStage&, const GrGLCaps&) const = 0;
bsalomon@google.comd698f772012-10-25 13:22:00 +000047 virtual GrGLEffect* createGLInstance(const GrEffect&) const = 0;
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000048
bsalomon@google.com396e61f2012-10-25 19:00:29 +000049 bool operator ==(const GrBackendEffectFactory& b) const {
bsalomon@google.com021fc732012-10-25 12:47:42 +000050 return fEffectClassID == b.fEffectClassID;
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000051 }
bsalomon@google.com396e61f2012-10-25 19:00:29 +000052 bool operator !=(const GrBackendEffectFactory& b) const {
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000053 return !(*this == b);
54 }
55
bsalomon@google.com289efe02012-05-21 20:57:59 +000056 virtual const char* name() const = 0;
57
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000058protected:
59 enum {
bsalomon@google.com021fc732012-10-25 12:47:42 +000060 kIllegalEffectClassID = 0,
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000061 };
62
bsalomon@google.com396e61f2012-10-25 19:00:29 +000063 GrBackendEffectFactory() {
bsalomon@google.com021fc732012-10-25 12:47:42 +000064 fEffectClassID = kIllegalEffectClassID;
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000065 }
66
bsalomon@google.com46fba0d2012-10-25 21:42:05 +000067 static EffectKey GenID() {
robertphillips@google.com4187a2f2012-11-05 01:31:44 +000068 GR_DEBUGCODE(static const int32_t kClassIDBits = 8 * sizeof(EffectKey) -
bsalomon@google.comb4a55b72012-11-02 20:45:37 +000069 kTextureKeyBits -
skia.committer@gmail.com1aa90cf2012-11-06 13:18:25 +000070 kEffectKeyBits);
bsalomon@google.com021fc732012-10-25 12:47:42 +000071 // fCurrEffectClassID has been initialized to kIllegalEffectClassID. The
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000072 // atomic inc returns the old value not the incremented value. So we add
73 // 1 to the returned value.
bsalomon@google.com021fc732012-10-25 12:47:42 +000074 int32_t id = sk_atomic_inc(&fCurrEffectClassID) + 1;
bsalomon@google.comb4a55b72012-11-02 20:45:37 +000075 GrAssert(id < (1 << kClassIDBits));
76 return static_cast<EffectKey>(id);
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000077 }
78
bsalomon@google.com46fba0d2012-10-25 21:42:05 +000079 EffectKey fEffectClassID;
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000080
81private:
bsalomon@google.com021fc732012-10-25 12:47:42 +000082 static int32_t fCurrEffectClassID;
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000083};
84
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000085#endif