1/*
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
8#ifndef GrEffectUnitTest_DEFINED
9#define GrEffectUnitTest_DEFINED
10
11#include "SkRandom.h"
12#include "SkTArray.h"
13#include "SkTypes.h"
14
15class SkMatrix;
16class GrDrawTargetCaps;
17
18namespace GrEffectUnitTest {
19// Used to access the dummy textures in TestCreate procs.
20enum {
21    kSkiaPMTextureIdx = 0,
22    kAlphaTextureIdx = 1,
23};
24
25/**
26 * A helper for use in GrEffect::TestCreate functions.
27 */
28const SkMatrix& TestMatrix(SkRandom*);
29
30}
31
32#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
33
34class GrContext;
35class GrEffectRef;
36class GrTexture;
37
38class GrEffectTestFactory : SkNoncopyable {
39public:
40
41    typedef GrEffectRef* (*CreateProc)(SkRandom*,
42                                       GrContext*,
43                                       const GrDrawTargetCaps& caps,
44                                       GrTexture* dummyTextures[]);
45
46    GrEffectTestFactory(CreateProc createProc) {
47        fCreateProc = createProc;
48        GetFactories()->push_back(this);
49    }
50
51    static GrEffectRef* CreateStage(SkRandom* random,
52                                    GrContext* context,
53                                    const GrDrawTargetCaps& caps,
54                                    GrTexture* dummyTextures[]) {
55        uint32_t idx = random->nextRangeU(0, GetFactories()->count() - 1);
56        GrEffectTestFactory* factory = (*GetFactories())[idx];
57        return factory->fCreateProc(random, context, caps, dummyTextures);
58    }
59
60private:
61    CreateProc fCreateProc;
62    static SkTArray<GrEffectTestFactory*, true>* GetFactories();
63};
64
65/** GrEffect subclasses should insert this macro in their declaration to be included in the
66 *  program generation unit test.
67 */
68#define GR_DECLARE_EFFECT_TEST                                                      \
69    static GrEffectTestFactory gTestFactory;                                        \
70    static GrEffectRef* TestCreate(SkRandom*,                                       \
71                                   GrContext*,                                      \
72                                   const GrDrawTargetCaps&,                         \
73                                   GrTexture* dummyTextures[2])
74
75/** GrEffect subclasses should insert this macro in their implementation file. They must then
76 *  also implement this static function:
77 *      GrEffect* TestCreate(SkRandom*,
78 *                           GrContext*,
79 *                           const GrDrawTargetCaps&,
80 *                           GrTexture* dummyTextures[2]);
81 * dummyTextures[] are valid textures that can optionally be used to construct GrTextureAccesses.
82 * The first texture has config kSkia8888_GrPixelConfig and the second has
83 * kAlpha_8_GrPixelConfig. TestCreate functions are also free to create additional textures using
84 * the GrContext.
85 */
86#define GR_DEFINE_EFFECT_TEST(Effect)                                               \
87    GrEffectTestFactory Effect :: gTestFactory(Effect :: TestCreate)
88
89#else // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
90
91// The unit test relies on static initializers. Just declare the TestCreate function so that
92// its definitions will compile.
93#define GR_DECLARE_EFFECT_TEST                                                      \
94    static GrEffectRef* TestCreate(SkRandom*,                                       \
95                                   GrContext*,                                      \
96                                   const GrDrawTargetCaps&,                         \
97                                   GrTexture* dummyTextures[2])
98#define GR_DEFINE_EFFECT_TEST(X)
99
100#endif // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
101#endif
102