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                         GrTexture* const textures[2])
     53             : fRandom(random)
     54             , fRenderTargetContext(renderTargetContext)
     55             , fContext(context) {
     56         fProxies[0] = GrSurfaceProxy::MakeWrapped(sk_ref_sp(textures[0]));
     57         fProxies[1] = GrSurfaceProxy::MakeWrapped(sk_ref_sp(textures[1]));
     58     }
     59     SkRandom* fRandom;
     60     const GrRenderTargetContext* fRenderTargetContext;
     61 
     62     GrContext* context() { return fContext; }
     63     GrResourceProvider* resourceProvider();
     64     const GrCaps* caps();
     65     sk_sp<GrTextureProxy> textureProxy(int index) { return fProxies[index]; }
     66 
     67 private:
     68     GrContext* fContext;
     69     sk_sp<GrTextureProxy> fProxies[2];
     70 };
     71 
     72 #if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
     73 
     74 class GrProcessor;
     75 class GrTexture;
     76 
     77 template <class Processor> class GrProcessorTestFactory : private SkNoncopyable {
     78 public:
     79     typedef sk_sp<Processor> (*MakeProc)(GrProcessorTestData*);
     80 
     81     GrProcessorTestFactory(MakeProc makeProc) {
     82         fMakeProc = makeProc;
     83         GetFactories()->push_back(this);
     84     }
     85 
     86     /** Pick a random factory function and create a processor.  */
     87     static sk_sp<Processor> Make(GrProcessorTestData* data) {
     88         VerifyFactoryCount();
     89         SkASSERT(GetFactories()->count());
     90         uint32_t idx = data->fRandom->nextRangeU(0, GetFactories()->count() - 1);
     91         return MakeIdx(idx, data);
     92     }
     93 
     94     /** Number of registered factory functions */
     95     static int Count() { return GetFactories()->count(); }
     96 
     97     /** Use factory function at Index idx to create a processor. */
     98     static sk_sp<Processor> MakeIdx(int idx, GrProcessorTestData* data) {
     99         GrProcessorTestFactory<Processor>* factory = (*GetFactories())[idx];
    100         sk_sp<Processor> processor = factory->fMakeProc(data);
    101         SkASSERT(processor);
    102         return processor;
    103     }
    104 
    105 private:
    106     /**
    107      * A test function which verifies the count of factories.
    108      */
    109     static void VerifyFactoryCount();
    110 
    111     MakeProc fMakeProc;
    112 
    113     static SkTArray<GrProcessorTestFactory<Processor>*, true>* GetFactories();
    114 };
    115 
    116 class GrXPFactoryTestFactory : private SkNoncopyable {
    117 public:
    118     using GetFn = const GrXPFactory*(GrProcessorTestData*);
    119 
    120     GrXPFactoryTestFactory(GetFn* getProc) : fGetProc(getProc) { GetFactories()->push_back(this); }
    121 
    122     static const GrXPFactory* Get(GrProcessorTestData* data) {
    123         VerifyFactoryCount();
    124         SkASSERT(GetFactories()->count());
    125         uint32_t idx = data->fRandom->nextRangeU(0, GetFactories()->count() - 1);
    126         const GrXPFactory* xpf = (*GetFactories())[idx]->fGetProc(data);
    127         SkASSERT(xpf);
    128         return xpf;
    129     }
    130 
    131 private:
    132     static void VerifyFactoryCount();
    133 
    134     GetFn* fGetProc;
    135     static SkTArray<GrXPFactoryTestFactory*, true>* GetFactories();
    136 };
    137 
    138 /** GrProcessor subclasses should insert this macro in their declaration to be included in the
    139  *  program generation unit test.
    140  */
    141 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST                                                         \
    142     static GrProcessorTestFactory<GrGeometryProcessor> gTestFactory SK_UNUSED;                     \
    143     static sk_sp<GrGeometryProcessor> TestCreate(GrProcessorTestData*)
    144 
    145 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST                                                         \
    146     static GrProcessorTestFactory<GrFragmentProcessor> gTestFactory SK_UNUSED;                     \
    147     static sk_sp<GrFragmentProcessor> TestCreate(GrProcessorTestData*)
    148 
    149 #define GR_DECLARE_XP_FACTORY_TEST                                                                 \
    150     static GrXPFactoryTestFactory gTestFactory SK_UNUSED;                                          \
    151     static const GrXPFactory* TestGet(GrProcessorTestData*)
    152 
    153 /** GrProcessor subclasses should insert this macro in their implementation file. They must then
    154  *  also implement this static function:
    155  *      GrProcessor* TestCreate(GrProcessorTestData*);
    156  */
    157 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(Effect)                                                  \
    158     GrProcessorTestFactory<GrFragmentProcessor> Effect::gTestFactory(Effect::TestCreate)
    159 
    160 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(Effect)                                                  \
    161     GrProcessorTestFactory<GrGeometryProcessor> Effect::gTestFactory(Effect::TestCreate)
    162 
    163 #define GR_DEFINE_XP_FACTORY_TEST(Factory)                                                         \
    164     GrXPFactoryTestFactory Factory::gTestFactory(Factory::TestGet)
    165 
    166 #else // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
    167 
    168 // The unit test relies on static initializers. Just declare the TestCreate function so that
    169 // its definitions will compile.
    170 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST                                                         \
    171     static sk_sp<GrFragmentProcessor> TestCreate(GrProcessorTestData*)
    172 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(X)
    173 
    174 // The unit test relies on static initializers. Just declare the TestCreate function so that
    175 // its definitions will compile.
    176 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST                                                         \
    177     static sk_sp<GrGeometryProcessor> TestCreate(GrProcessorTestData*)
    178 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(X)
    179 
    180 // The unit test relies on static initializers. Just declare the TestGet function so that
    181 // its definitions will compile.
    182 #define GR_DECLARE_XP_FACTORY_TEST                                                                 \
    183     const GrXPFactory* TestGet(GrProcessorTestData*)
    184 #define GR_DEFINE_XP_FACTORY_TEST(X)
    185 
    186 #endif  // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
    187 #else   // GR_TEST_UTILS
    188     #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST
    189     #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST
    190     #define GR_DECLARE_XP_FACTORY_TEST
    191     #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(...)
    192     #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(...)
    193     #define GR_DEFINE_XP_FACTORY_TEST(...)
    194     #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST
    195     #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(...)
    196     #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST
    197     #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(...)
    198     #define GR_DECLARE_XP_FACTORY_TEST
    199     #define GR_DEFINE_XP_FACTORY_TEST(...)
    200 #endif  // GR_TEST_UTILS
    201 #endif  // GrProcessorUnitTest_DEFINED
    202