1681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com/*
2681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com * Copyright 2012 Google Inc.
3681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com *
4681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com * Use of this source code is governed by a BSD-style license that can be
5681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com * found in the LICENSE file.
6681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com */
7681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com
8681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com#ifndef GrTBackendEffectFactory_DEFINED
9681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com#define GrTBackendEffectFactory_DEFINED
10681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com
11681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com#include "GrBackendEffectFactory.h"
12c85be68b6ac65e4c9f3c1ce047fe807263fb8c12bsalomon@google.com#include "GrDrawEffect.h"
1314d0a31192c274848f696ea7fd8c343ad9d6762dcommit-bot@chromium.org#include "gl/GrGLProgramEffects.h"
14681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com
15681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com/**
16681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com * Implements GrBackendEffectFactory for a GrEffect subclass as a singleton.
17681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com */
18681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.comtemplate <typename EffectClass>
19681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.comclass GrTBackendEffectFactory : public GrBackendEffectFactory {
20681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com
21681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.compublic:
22681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com    typedef typename EffectClass::GLEffect GLEffect;
23681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com
24681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com    /** Returns a human-readable name that is accessible via GrEffect or
25681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com        GrGLEffect and is consistent between the two of them.
26681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com     */
27681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com    virtual const char* name() const SK_OVERRIDE { return EffectClass::Name(); }
28681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com
29681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com    /** Returns a value that identifies the GLSL shader code generated by
30681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com        a GrEffect. This enables caching of generated shaders. Part of the
31681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com        id identifies the GrEffect subclass. The remainder is based
32681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com        on the aspects of the GrEffect object's configuration that affect
33681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com        GLSL code generation. */
34c85be68b6ac65e4c9f3c1ce047fe807263fb8c12bsalomon@google.com    virtual EffectKey glEffectKey(const GrDrawEffect& drawEffect,
35681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com                                  const GrGLCaps& caps) const SK_OVERRIDE {
36be798415622630533a602b0941ec8314fb0fd019tfarina@chromium.org        SkASSERT(kIllegalEffectClassID != fEffectClassID);
37c85be68b6ac65e4c9f3c1ce047fe807263fb8c12bsalomon@google.com        EffectKey effectKey = GLEffect::GenKey(drawEffect, caps);
3814d0a31192c274848f696ea7fd8c343ad9d6762dcommit-bot@chromium.org        EffectKey textureKey = GrGLProgramEffects::GenTextureKey(drawEffect, caps);
3914d0a31192c274848f696ea7fd8c343ad9d6762dcommit-bot@chromium.org        EffectKey transformKey = GrGLProgramEffects::GenTransformKey(drawEffect);
4014d0a31192c274848f696ea7fd8c343ad9d6762dcommit-bot@chromium.org        EffectKey attribKey = GrGLProgramEffects::GenAttribKey(drawEffect);
41f9e5f501b4e6c9e17b19730ef1f32caa407fb80bcommit-bot@chromium.org#ifdef SK_DEBUG
42c0c9c17e75f88d8b5c7a0b120ad7983d82feb8debsalomon@google.com        static const EffectKey kIllegalEffectKeyMask = (uint16_t) (~((1U << kEffectKeyBits) - 1));
43c0c9c17e75f88d8b5c7a0b120ad7983d82feb8debsalomon@google.com        SkASSERT(!(kIllegalEffectKeyMask & effectKey));
44681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com
45681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com        static const EffectKey kIllegalTextureKeyMask = (uint16_t) (~((1U << kTextureKeyBits) - 1));
46be798415622630533a602b0941ec8314fb0fd019tfarina@chromium.org        SkASSERT(!(kIllegalTextureKeyMask & textureKey));
47f55d4ecae1083f2900c7dc5b508335e7c48da072commit-bot@chromium.org
48c0c9c17e75f88d8b5c7a0b120ad7983d82feb8debsalomon@google.com        static const EffectKey kIllegalTransformKeyMask = (uint16_t) (~((1U << kTransformKeyBits) - 1));
49c0c9c17e75f88d8b5c7a0b120ad7983d82feb8debsalomon@google.com        SkASSERT(!(kIllegalTransformKeyMask & transformKey));
50c0c9c17e75f88d8b5c7a0b120ad7983d82feb8debsalomon@google.com
51f55d4ecae1083f2900c7dc5b508335e7c48da072commit-bot@chromium.org        static const EffectKey kIllegalAttribKeyMask = (uint16_t) (~((1U << kAttribKeyBits) - 1));
52be798415622630533a602b0941ec8314fb0fd019tfarina@chromium.org        SkASSERT(!(kIllegalAttribKeyMask & textureKey));
53c0c9c17e75f88d8b5c7a0b120ad7983d82feb8debsalomon@google.com
54c0c9c17e75f88d8b5c7a0b120ad7983d82feb8debsalomon@google.com        static const EffectKey kIllegalClassIDMask = (uint16_t) (~((1U << kClassIDBits) - 1));
55c0c9c17e75f88d8b5c7a0b120ad7983d82feb8debsalomon@google.com        SkASSERT(!(kIllegalClassIDMask & fEffectClassID));
56681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com#endif
57c0c9c17e75f88d8b5c7a0b120ad7983d82feb8debsalomon@google.com        return (fEffectClassID << (kEffectKeyBits+kTextureKeyBits+kTransformKeyBits+kAttribKeyBits)) |
58c0c9c17e75f88d8b5c7a0b120ad7983d82feb8debsalomon@google.com               (attribKey << (kEffectKeyBits+kTextureKeyBits+kTransformKeyBits)) |
59c0c9c17e75f88d8b5c7a0b120ad7983d82feb8debsalomon@google.com               (transformKey << (kEffectKeyBits+kTextureKeyBits)) |
60c0c9c17e75f88d8b5c7a0b120ad7983d82feb8debsalomon@google.com               (textureKey << kEffectKeyBits) |
61c0c9c17e75f88d8b5c7a0b120ad7983d82feb8debsalomon@google.com               (effectKey);
62681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com    }
63681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com
64681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com    /** Returns a new instance of the appropriate *GL* implementation class
65681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com        for the given GrEffect; caller is responsible for deleting
66681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com        the object. */
67c85be68b6ac65e4c9f3c1ce047fe807263fb8c12bsalomon@google.com    virtual GLEffect* createGLInstance(const GrDrawEffect& drawEffect) const SK_OVERRIDE {
68c85be68b6ac65e4c9f3c1ce047fe807263fb8c12bsalomon@google.com        return SkNEW_ARGS(GLEffect, (*this, drawEffect));
69681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com    }
70681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com
71681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com    /** This class is a singleton. This function returns the single instance.
72681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com     */
73681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com    static const GrBackendEffectFactory& getInstance() {
74681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com        static SkAlignedSTStorage<1, GrTBackendEffectFactory> gInstanceMem;
75681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com        static const GrTBackendEffectFactory* gInstance;
76681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com        if (!gInstance) {
77681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com            gInstance = SkNEW_PLACEMENT(gInstanceMem.get(),
78681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com                                        GrTBackendEffectFactory);
79681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com        }
80681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com        return *gInstance;
81681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com    }
82681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com
83681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.comprotected:
84681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com    GrTBackendEffectFactory() {
85c0c9c17e75f88d8b5c7a0b120ad7983d82feb8debsalomon@google.com        fEffectClassID = GenID();
86681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com    }
87681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com};
88681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com
89681e58ef9a3b810f1f057252cbd6db194f45b946bsalomon@google.com#endif
90