Home | History | Annotate | Download | only in gpu
      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 GrProcessorUnitTest_DEFINED
      9 #define GrProcessorUnitTest_DEFINED
     10 
     11 #include "SkTypes.h"
     12 
     13 #if GR_TEST_UTILS
     14 
     15 #include "../private/GrTextureProxy.h"
     16 #include "../private/SkTArray.h"
     17 #include "GrTestUtils.h"
     18 
     19 class SkMatrix;
     20 class GrCaps;
     21 class GrContext;
     22 class GrRenderTargetContext;
     23 struct GrProcessorTestData;
     24 class GrTexture;
     25 class GrXPFactory;
     26 
     27 namespace GrProcessorUnitTest {
     28 
     29 // Used to access the dummy textures in TestCreate procs.
     30 enum {
     31     kSkiaPMTextureIdx = 0,
     32     kAlphaTextureIdx = 1,
     33 };
     34 
     35 /** This allows parent FPs to implement a test create with known leaf children in order to avoid
     36 creating an unbounded FP tree which may overflow various shader limits. */
     37 sk_sp<GrFragmentProcessor> MakeChildFP(GrProcessorTestData*);
     38 
     39 }
     40 
     41 /*
     42  * GrProcessorTestData is an argument struct to TestCreate functions
     43  * fTextures are valid textures that can optionally be used to construct
     44  * TextureSampler. The first texture has config kSkia8888_GrPixelConfig and the second has
     45  * kAlpha_8_GrPixelConfig. TestCreate functions are also free to create additional textures using
     46  * the GrContext.
     47  */
     48 struct GrProcessorTestData {
     49     GrProcessorTestData(SkRandom* random,
     50                         GrContext* context,
     51                         const GrRenderTargetContext* renderTargetContext,
     52                         sk_sp<GrTextureProxy> proxies[2])
     53             : fRandom(random)
     54             , fRenderTargetContext(renderTargetContext)
     55             , fContext(context) {
     56         SkASSERT(proxies[0] && proxies[1]);
     57         fProxies[0] = proxies[0];
     58         fProxies[1] = proxies[1];
     59     }
     60     SkRandom* fRandom;
     61     const GrRenderTargetContext* fRenderTargetContext;
     62 
     63     GrContext* context() { return fContext; }
     64     GrResourceProvider* resourceProvider();
     65     const GrCaps* caps();
     66     sk_sp<GrTextureProxy> textureProxy(int index) { return fProxies[index]; }
     67 
     68 private:
     69     GrContext* fContext;
     70     sk_sp<GrTextureProxy> fProxies[2];
     71 };
     72 
     73 #if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
     74 
     75 class GrProcessor;
     76 class GrTexture;
     77 
     78 template <class Processor> class GrProcessorTestFactory : private SkNoncopyable {
     79 public:
     80     typedef sk_sp<Processor> (*MakeProc)(GrProcessorTestData*);
     81 
     82     GrProcessorTestFactory(MakeProc makeProc) {
     83         fMakeProc = makeProc;
     84         GetFactories()->push_back(this);
     85     }
     86 
     87     /** Pick a random factory function and create a processor.  */
     88     static sk_sp<Processor> Make(GrProcessorTestData* data) {
     89         VerifyFactoryCount();
     90         SkASSERT(GetFactories()->count());
     91         uint32_t idx = data->fRandom->nextRangeU(0, GetFactories()->count() - 1);
     92         return MakeIdx(idx, data);
     93     }
     94 
     95     /** Number of registered factory functions */
     96     static int Count() { return GetFactories()->count(); }
     97 
     98     /** Use factory function at Index idx to create a processor. */
     99     static sk_sp<Processor> MakeIdx(int idx, GrProcessorTestData* data) {
    100         GrProcessorTestFactory<Processor>* factory = (*GetFactories())[idx];
    101         sk_sp<Processor> processor = factory->fMakeProc(data);
    102         SkASSERT(processor);
    103         return processor;
    104     }
    105 
    106 private:
    107     /**
    108      * A test function which verifies the count of factories.
    109      */
    110     static void VerifyFactoryCount();
    111 
    112     MakeProc fMakeProc;
    113 
    114     static SkTArray<GrProcessorTestFactory<Processor>*, true>* GetFactories();
    115 };
    116 
    117 class GrXPFactoryTestFactory : private SkNoncopyable {
    118 public:
    119     using GetFn = const GrXPFactory*(GrProcessorTestData*);
    120 
    121     GrXPFactoryTestFactory(GetFn* getProc) : fGetProc(getProc) { GetFactories()->push_back(this); }
    122 
    123     static const GrXPFactory* Get(GrProcessorTestData* data) {
    124         VerifyFactoryCount();
    125         SkASSERT(GetFactories()->count());
    126         uint32_t idx = data->fRandom->nextRangeU(0, GetFactories()->count() - 1);
    127         const GrXPFactory* xpf = (*GetFactories())[idx]->fGetProc(data);
    128         SkASSERT(xpf);
    129         return xpf;
    130     }
    131 
    132 private:
    133     static void VerifyFactoryCount();
    134 
    135     GetFn* fGetProc;
    136     static SkTArray<GrXPFactoryTestFactory*, true>* GetFactories();
    137 };
    138 
    139 /** GrProcessor subclasses should insert this macro in their declaration to be included in the
    140  *  program generation unit test.
    141  */
    142 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST                                                         \
    143     static GrProcessorTestFactory<GrGeometryProcessor> gTestFactory SK_UNUSED;                     \
    144     static sk_sp<GrGeometryProcessor> TestCreate(GrProcessorTestData*);
    145 
    146 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST                                                         \
    147     static GrProcessorTestFactory<GrFragmentProcessor> gTestFactory SK_UNUSED;                     \
    148     static sk_sp<GrFragmentProcessor> TestCreate(GrProcessorTestData*);
    149 
    150 #define GR_DECLARE_XP_FACTORY_TEST                                                                 \
    151     static GrXPFactoryTestFactory gTestFactory SK_UNUSED;                                          \
    152     static const GrXPFactory* TestGet(GrProcessorTestData*);
    153 
    154 /** GrProcessor subclasses should insert this macro in their implementation file. They must then
    155  *  also implement this static function:
    156  *      GrProcessor* TestCreate(GrProcessorTestData*);
    157  */
    158 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(Effect)                                                  \
    159     GrProcessorTestFactory<GrFragmentProcessor> Effect::gTestFactory(Effect::TestCreate)
    160 
    161 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(Effect)                                                  \
    162     GrProcessorTestFactory<GrGeometryProcessor> Effect::gTestFactory(Effect::TestCreate)
    163 
    164 #define GR_DEFINE_XP_FACTORY_TEST(Factory)                                                         \
    165     GrXPFactoryTestFactory Factory::gTestFactory(Factory::TestGet)
    166 
    167 #else // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
    168 
    169 // The unit test relies on static initializers. Just declare the TestCreate function so that
    170 // its definitions will compile.
    171 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST                                                         \
    172     static sk_sp<GrFragmentProcessor> TestCreate(GrProcessorTestData*);
    173 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(X)
    174 
    175 // The unit test relies on static initializers. Just declare the TestCreate function so that
    176 // its definitions will compile.
    177 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST                                                         \
    178     static sk_sp<GrGeometryProcessor> TestCreate(GrProcessorTestData*);
    179 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(X)
    180 
    181 // The unit test relies on static initializers. Just declare the TestGet function so that
    182 // its definitions will compile.
    183 #define GR_DECLARE_XP_FACTORY_TEST                                                                 \
    184     const GrXPFactory* TestGet(GrProcessorTestData*);
    185 #define GR_DEFINE_XP_FACTORY_TEST(X)
    186 
    187 #endif  // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
    188 #else   // GR_TEST_UTILS
    189     #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST
    190     #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST
    191     #define GR_DECLARE_XP_FACTORY_TEST
    192     #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(...)
    193     #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(...)
    194     #define GR_DEFINE_XP_FACTORY_TEST(...)
    195     #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST
    196     #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(...)
    197     #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST
    198     #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(...)
    199     #define GR_DECLARE_XP_FACTORY_TEST
    200     #define GR_DEFINE_XP_FACTORY_TEST(...)
    201 #endif  // GR_TEST_UTILS
    202 #endif  // GrProcessorUnitTest_DEFINED
    203