blob: 7b437117491e03a570e34f4976e96228cc774790 [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.comb4a55b72012-11-02 20:45:37 +000035 kEffectKeyBits = 12,
bsalomon@google.com46fba0d2012-10-25 21:42:05 +000036 /**
37 * Some aspects of the generated code may be determined by the particular textures that are
38 * associated with the effect. These manipulations are performed by GrGLShaderBuilder beyond
39 * GrGLEffects' control. So there is a dedicated part of the key which is combined
40 * automatically with the bits produced by GrGLEffect::GenKey().
41 */
42 kTextureKeyBits = 6
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000043 };
44
bsalomon@google.com2eaaefd2012-10-29 19:51:22 +000045 virtual EffectKey glEffectKey(const GrEffectStage&, const GrGLCaps&) const = 0;
bsalomon@google.comd698f772012-10-25 13:22:00 +000046 virtual GrGLEffect* createGLInstance(const GrEffect&) const = 0;
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000047
bsalomon@google.com396e61f2012-10-25 19:00:29 +000048 bool operator ==(const GrBackendEffectFactory& b) const {
bsalomon@google.com021fc732012-10-25 12:47:42 +000049 return fEffectClassID == b.fEffectClassID;
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.comae4f96a2012-05-18 19:54:48 +000052 return !(*this == b);
53 }
54
bsalomon@google.com289efe02012-05-21 20:57:59 +000055 virtual const char* name() const = 0;
56
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000057protected:
58 enum {
bsalomon@google.com021fc732012-10-25 12:47:42 +000059 kIllegalEffectClassID = 0,
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000060 };
61
bsalomon@google.com396e61f2012-10-25 19:00:29 +000062 GrBackendEffectFactory() {
bsalomon@google.com021fc732012-10-25 12:47:42 +000063 fEffectClassID = kIllegalEffectClassID;
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000064 }
65
bsalomon@google.com46fba0d2012-10-25 21:42:05 +000066 static EffectKey GenID() {
bsalomon@google.comb4a55b72012-11-02 20:45:37 +000067 static const int32_t kClassIDBits = 8 * sizeof(EffectKey) -
68 kTextureKeyBits -
69 kEffectKeyBits;
bsalomon@google.com021fc732012-10-25 12:47:42 +000070 // fCurrEffectClassID has been initialized to kIllegalEffectClassID. The
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000071 // atomic inc returns the old value not the incremented value. So we add
72 // 1 to the returned value.
bsalomon@google.com021fc732012-10-25 12:47:42 +000073 int32_t id = sk_atomic_inc(&fCurrEffectClassID) + 1;
bsalomon@google.comb4a55b72012-11-02 20:45:37 +000074 GrAssert(id < (1 << kClassIDBits));
75 return static_cast<EffectKey>(id);
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000076 }
77
bsalomon@google.com46fba0d2012-10-25 21:42:05 +000078 EffectKey fEffectClassID;
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000079
80private:
bsalomon@google.com021fc732012-10-25 12:47:42 +000081 static int32_t fCurrEffectClassID;
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000082};
83
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000084#endif