/* * Copyright 2012 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef GrProcessorUnitTest_DEFINED #define GrProcessorUnitTest_DEFINED #include "include/core/SkTypes.h" #if defined(GPU_TEST_UTILS) #include "include/core/SkString.h" #include "include/private/base/SkNoncopyable.h" #include "include/private/base/SkTArray.h" #include "src/gpu/ganesh/GrFragmentProcessor.h" #include "src/gpu/ganesh/GrSurfaceProxyView.h" // IWYU pragma: keep #include #include class GrCaps; class GrGeometryProcessor; class GrProcessorTestData; class GrProxyProvider; class GrRecordingContext; class GrXPFactory; class SkArenaAlloc; class SkRandom; enum SkAlphaType : int; enum class GrColorType; namespace GrProcessorUnitTest { /** This allows parent FPs to implement a test create with known leaf children in order to avoid * creating an unbounded FP tree which may overflow various shader limits. * MakeOptionalChildFP is the same as MakeChildFP, but can return null. */ std::unique_ptr MakeChildFP(GrProcessorTestData*); std::unique_ptr MakeOptionalChildFP(GrProcessorTestData*); } // namespace GrProcessorUnitTest /** GrProcessorTestData is an argument struct to TestCreate functions * fTextures are valid textures that can optionally be used to construct * TextureSampler. The first texture has a RGBA8 format and the second has Alpha8 format for the * specific backend API. TestCreate functions are also free to create additional textures using * the GrContext. */ class GrProcessorTestData { public: using ViewInfo = std::tuple; GrProcessorTestData(SkRandom* random, GrRecordingContext* context, int maxTreeDepth, int numViews, const ViewInfo views[]); GrProcessorTestData(SkRandom* random, GrRecordingContext* context, int maxTreeDepth, int numViews, const ViewInfo views[], std::unique_ptr inputFP); GrProcessorTestData(const GrProcessorTestData&) = delete; ~GrProcessorTestData(); GrRecordingContext* context() { return fContext; } GrProxyProvider* proxyProvider(); const GrCaps* caps(); SkArenaAlloc* allocator() { return fArena.get(); } std::unique_ptr inputFP(); ViewInfo randomView(); ViewInfo randomAlphaOnlyView(); SkRandom* fRandom; int fCurrentTreeDepth = 0; int fMaxTreeDepth = 1; private: GrRecordingContext* fContext; skia_private::TArray fViews; std::unique_ptr fArena; std::unique_ptr fInputFP; }; template class GrProcessorTestFactory : private SkNoncopyable { public: using MakeProc = ProcessorSmartPtr (*)(GrProcessorTestData*); GrProcessorTestFactory(MakeProc makeProc, const char* name); /** Pick a random factory function and create a processor. */ static ProcessorSmartPtr Make(GrProcessorTestData* data); /** Use factory function at Index idx to create a processor. */ static ProcessorSmartPtr MakeIdx(int idx, GrProcessorTestData* data); /** Number of registered factory functions */ static int Count(); private: /** A test function which verifies the count of factories. */ static void VerifyFactoryCount(); static skia_private::TArray*, true>* GetFactories(); MakeProc fMakeProc; SkString fName; }; using GrFragmentProcessorTestFactory = GrProcessorTestFactory>; using GrGeometryProcessorTestFactory = GrProcessorTestFactory; class GrXPFactoryTestFactory : private SkNoncopyable { public: using GetFn = const GrXPFactory*(GrProcessorTestData*); GrXPFactoryTestFactory(GetFn* getProc); static const GrXPFactory* Get(GrProcessorTestData* data); private: /** A test function which verifies the count of factories. */ static void VerifyFactoryCount(); static skia_private::TArray* GetFactories(); GetFn* fGetProc; }; #if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS /** GrProcessor subclasses should insert this macro in their declaration to be included in the * program generation unit test. */ #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST \ [[maybe_unused]] static GrGeometryProcessorTestFactory* gTestFactory; \ static GrGeometryProcessor* TestCreate(GrProcessorTestData*); #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST \ [[maybe_unused]] static GrFragmentProcessorTestFactory* gTestFactory; \ static std::unique_ptr TestCreate(GrProcessorTestData*); #define GR_DECLARE_XP_FACTORY_TEST \ [[maybe_unused]] static GrXPFactoryTestFactory* gTestFactory; \ static const GrXPFactory* TestGet(GrProcessorTestData*); /** GrProcessor subclasses should insert this macro in their implementation file. They must then * also implement this static function: * GrProcessor* TestCreate(GrProcessorTestData*); */ #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(Effect) \ GrFragmentProcessorTestFactory* Effect::gTestFactory = \ new GrFragmentProcessorTestFactory(Effect::TestCreate, #Effect); #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(Effect) \ GrGeometryProcessorTestFactory* Effect::gTestFactory = \ new GrGeometryProcessorTestFactory(Effect::TestCreate, #Effect); #define GR_DEFINE_XP_FACTORY_TEST(Factory) \ GrXPFactoryTestFactory* Factory::gTestFactory = new GrXPFactoryTestFactory(Factory::TestGet); #else // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS // The unit test relies on static initializers. Just declare the TestCreate function so that // its definitions will compile. #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST \ static std::unique_ptr TestCreate(GrProcessorTestData*); #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(X) // The unit test relies on static initializers. Just declare the TestCreate function so that // its definitions will compile. #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST \ static GrGeometryProcessor* TestCreate(GrProcessorTestData*); #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(X) // The unit test relies on static initializers. Just declare the TestGet function so that // its definitions will compile. #define GR_DECLARE_XP_FACTORY_TEST \ const GrXPFactory* TestGet(GrProcessorTestData*); #define GR_DEFINE_XP_FACTORY_TEST(X) #endif // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS #else // defined(GPU_TEST_UTILS) #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST #define GR_DECLARE_XP_FACTORY_TEST #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(...) #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(...) #define GR_DEFINE_XP_FACTORY_TEST(...) #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(...) #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(...) #define GR_DECLARE_XP_FACTORY_TEST #define GR_DEFINE_XP_FACTORY_TEST(...) #endif // defined(GPU_TEST_UTILS) #endif // GrProcessorUnitTest_DEFINED