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 "../private/SkTArray.h"
     12 #include "GrTestUtils.h"
     13 #include "SkTypes.h"
     14 
     15 class SkMatrix;
     16 class GrCaps;
     17 class GrContext;
     18 class GrRenderTarget;
     19 struct GrProcessorTestData;
     20 
     21 namespace GrProcessorUnitTest {
     22 
     23 // Used to access the dummy textures in TestCreate procs.
     24 enum {
     25     kSkiaPMTextureIdx = 0,
     26     kAlphaTextureIdx = 1,
     27 };
     28 
     29 /** This allows parent FPs to implement a test create with known leaf children in order to avoid
     30 creating an unbounded FP tree which may overflow various shader limits. */
     31 const GrFragmentProcessor* CreateChildFP(GrProcessorTestData*);
     32 
     33 }
     34 
     35 /*
     36  * GrProcessorTestData is an argument struct to TestCreate functions
     37  * fTextures are valid textures that can optionally be used to construct
     38  * GrTextureAccesses. The first texture has config kSkia8888_GrPixelConfig and the second has
     39  * kAlpha_8_GrPixelConfig. TestCreate functions are also free to create additional textures using
     40  * the GrContext.
     41  */
     42 struct GrProcessorTestData {
     43     GrProcessorTestData(SkRandom* random,
     44                         GrContext* context,
     45                         const GrCaps* caps,
     46                         const GrRenderTarget* rt,
     47                         GrTexture* textures[2])
     48         : fRandom(random)
     49         , fContext(context)
     50         , fCaps(caps)
     51         , fRenderTarget(rt) {
     52         fTextures[0] = textures[0];
     53         fTextures[1] = textures[1];
     54     }
     55     SkRandom* fRandom;
     56     GrContext* fContext;
     57     const GrCaps* fCaps;
     58     const GrRenderTarget* fRenderTarget;
     59     GrTexture* fTextures[2];
     60 };
     61 
     62 #if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
     63 
     64 class GrProcessor;
     65 class GrTexture;
     66 
     67 template <class Processor> class GrProcessorTestFactory : SkNoncopyable {
     68 public:
     69     typedef const Processor* (*CreateProc)(GrProcessorTestData*);
     70 
     71     GrProcessorTestFactory(CreateProc createProc) {
     72         fCreateProc = createProc;
     73         GetFactories()->push_back(this);
     74     }
     75 
     76     /** Pick a random factory function and create a processor.  */
     77     static const Processor* Create(GrProcessorTestData* data) {
     78         VerifyFactoryCount();
     79         SkASSERT(GetFactories()->count());
     80         uint32_t idx = data->fRandom->nextRangeU(0, GetFactories()->count() - 1);
     81         return CreateIdx(idx, data);
     82     }
     83 
     84     /** Number of registered factory functions */
     85     static int Count() { return GetFactories()->count(); }
     86 
     87     /** Use factory function at Index idx to create a processor. */
     88     static const Processor* CreateIdx(int idx, GrProcessorTestData* data) {
     89         GrProcessorTestFactory<Processor>* factory = (*GetFactories())[idx];
     90         return factory->fCreateProc(data);
     91     }
     92 
     93     /*
     94      * A test function which verifies the count of factories.
     95      */
     96     static void VerifyFactoryCount();
     97 
     98 private:
     99     CreateProc fCreateProc;
    100 
    101     static SkTArray<GrProcessorTestFactory<Processor>*, true>* GetFactories();
    102 };
    103 
    104 /** GrProcessor subclasses should insert this macro in their declaration to be included in the
    105  *  program generation unit test.
    106  */
    107 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST                                                         \
    108     static GrProcessorTestFactory<GrGeometryProcessor> gTestFactory SK_UNUSED;                     \
    109     static const GrGeometryProcessor* TestCreate(GrProcessorTestData*)
    110 
    111 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST                                                         \
    112     static GrProcessorTestFactory<GrFragmentProcessor> gTestFactory SK_UNUSED;                     \
    113     static const GrFragmentProcessor* TestCreate(GrProcessorTestData*)
    114 
    115 #define GR_DECLARE_XP_FACTORY_TEST                                                                 \
    116     static GrProcessorTestFactory<GrXPFactory> gTestFactory SK_UNUSED;                             \
    117     static const GrXPFactory* TestCreate(GrProcessorTestData*)
    118 
    119 /** GrProcessor subclasses should insert this macro in their implementation file. They must then
    120  *  also implement this static function:
    121  *      GrProcessor* TestCreate(GrProcessorTestData*);
    122  */
    123 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(Effect)                                                  \
    124     GrProcessorTestFactory<GrFragmentProcessor> Effect :: gTestFactory(Effect :: TestCreate)
    125 
    126 #define GR_DEFINE_XP_FACTORY_TEST(Factory)                                                         \
    127     GrProcessorTestFactory<GrXPFactory> Factory :: gTestFactory(Factory :: TestCreate)
    128 
    129 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(Effect)                                                  \
    130     GrProcessorTestFactory<GrGeometryProcessor> Effect :: gTestFactory(Effect :: TestCreate)
    131 
    132 #else // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
    133 
    134 // The unit test relies on static initializers. Just declare the TestCreate function so that
    135 // its definitions will compile.
    136 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST                                                         \
    137     static const GrFragmentProcessor* TestCreate(GrProcessorTestData*)
    138 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(X)
    139 
    140 // The unit test relies on static initializers. Just declare the TestCreate function so that
    141 // its definitions will compile.
    142 #define GR_DECLARE_XP_FACTORY_TEST                                                                 \
    143     static const GrXPFactory* TestCreate(GrProcessorTestData*)
    144 #define GR_DEFINE_XP_FACTORY_TEST(X)
    145 
    146 // The unit test relies on static initializers. Just declare the TestCreate function so that
    147 // its definitions will compile.
    148 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST                                                         \
    149     static const GrGeometryProcessor* TestCreate(GrProcessorTestData*)
    150 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(X)
    151 
    152 #endif // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
    153 #endif
    154