1 #ifndef _MOVIT_TEST_UTIL_H 2 #define _MOVIT_TEST_UTIL_H 1 3 4 #include <epoxy/gl.h> 5 #ifdef HAVE_BENCHMARK 6 #include <benchmark/benchmark.h> 7 #endif 8 #include "effect_chain.h" 9 #include "fp16.h" 10 #include "image_format.h" 11 12 namespace movit { 13 14 class Input; 15 16 class EffectChainTester { 17 public: 18 EffectChainTester(const float *data, unsigned width, unsigned height, 19 MovitPixelFormat pixel_format = FORMAT_GRAYSCALE, 20 Colorspace color_space = COLORSPACE_sRGB, 21 GammaCurve gamma_curve = GAMMA_LINEAR, 22 GLenum framebuffer_format = GL_RGBA16F_ARB); 23 ~EffectChainTester(); 24 get_chain()25 EffectChain *get_chain() { return &chain; } 26 Input *add_input(const float *data, MovitPixelFormat pixel_format, Colorspace color_space, GammaCurve gamma_curve, int input_width = -1, int input_height = -1); 27 Input *add_input(const fp16_int_t *data, MovitPixelFormat pixel_format, Colorspace color_space, GammaCurve gamma_curve, int input_width = -1, int input_height = -1); 28 Input *add_input(const unsigned char *data, MovitPixelFormat pixel_format, Colorspace color_space, GammaCurve gamma_curve, int input_width = -1, int input_height = -1); 29 30 void run(float *out_data, GLenum format, Colorspace color_space, GammaCurve gamma_curve, OutputAlphaFormat alpha_format = OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED); 31 void run(const std::vector<float *> &out_data, GLenum format, Colorspace color_space, GammaCurve gamma_curve, OutputAlphaFormat alpha_format = OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED); 32 void run(unsigned char *out_data, GLenum format, Colorspace color_space, GammaCurve gamma_curve, OutputAlphaFormat alpha_format = OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED); 33 void run(const std::vector<unsigned char *> &out_data, GLenum format, Colorspace color_space, GammaCurve gamma_curve, OutputAlphaFormat alpha_format = OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED); 34 void run(uint16_t *out_data, GLenum format, Colorspace color_space, GammaCurve gamma_curve, OutputAlphaFormat alpha_format = OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED); 35 void run_10_10_10_2(uint32_t *out_data, GLenum format, Colorspace color_space, GammaCurve gamma_curve, OutputAlphaFormat alpha_format = OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED); 36 37 #ifdef HAVE_BENCHMARK 38 void benchmark(benchmark::State &state, float *out_data, GLenum format, Colorspace color_space, GammaCurve gamma_curve, OutputAlphaFormat alpha_format = OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED); 39 void benchmark(benchmark::State &state, const std::vector<float *> &out_data, GLenum format, Colorspace color_space, GammaCurve gamma_curve, OutputAlphaFormat alpha_format = OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED); 40 void benchmark(benchmark::State &state, fp16_int_t *out_data, GLenum format, Colorspace color_space, GammaCurve gamma_curve, OutputAlphaFormat alpha_format = OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED); 41 void benchmark(benchmark::State &state, const std::vector<fp16_int_t *> &out_data, GLenum format, Colorspace color_space, GammaCurve gamma_curve, OutputAlphaFormat alpha_format = OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED); 42 void benchmark(benchmark::State &state, unsigned char *out_data, GLenum format, Colorspace color_space, GammaCurve gamma_curve, OutputAlphaFormat alpha_format = OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED); 43 void benchmark(benchmark::State &state, const std::vector<unsigned char *> &out_data, GLenum format, Colorspace color_space, GammaCurve gamma_curve, OutputAlphaFormat alpha_format = OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED); 44 void benchmark(benchmark::State &state, uint16_t *out_data, GLenum format, Colorspace color_space, GammaCurve gamma_curve, OutputAlphaFormat alpha_format = OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED); 45 void benchmark_10_10_10_2(benchmark::State &state, uint32_t *out_data, GLenum format, Colorspace color_space, GammaCurve gamma_curve, OutputAlphaFormat alpha_format = OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED); 46 #endif 47 48 void add_output(const ImageFormat &format, OutputAlphaFormat alpha_format); 49 void add_ycbcr_output(const ImageFormat &format, OutputAlphaFormat alpha_format, const YCbCrFormat &ycbcr_format, YCbCrOutputSplitting output_splitting = YCBCR_OUTPUT_INTERLEAVED, GLenum output_type = GL_UNSIGNED_BYTE); 50 51 private: 52 void finalize_chain(Colorspace color_space, GammaCurve gamma_curve, OutputAlphaFormat alpha_format); 53 54 template<class T> 55 void internal_run(const std::vector<T *> &out_data, GLenum format, Colorspace color_space, GammaCurve gamma_curve, OutputAlphaFormat alpha_format = OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED 56 #ifdef HAVE_BENCHMARK 57 , benchmark::State *state = nullptr 58 #endif 59 ); 60 61 EffectChain chain; 62 unsigned width, height; 63 GLenum framebuffer_format; 64 bool output_added; 65 bool finalized; 66 }; 67 68 void expect_equal(const float *ref, const float *result, unsigned width, unsigned height, float largest_difference_limit = 1.5 / 255.0, float rms_limit = 0.2 / 255.0); 69 void expect_equal(const unsigned char *ref, const unsigned char *result, unsigned width, unsigned height, unsigned largest_difference_limit = 1, float rms_limit = 0.2); 70 void expect_equal(const uint16_t *ref, const uint16_t *result, unsigned width, unsigned height, unsigned largest_difference_limit = 1, float rms_limit = 0.2); 71 void expect_equal(const int *ref, const int *result, unsigned width, unsigned height, unsigned largest_difference_limit = 1, float rms_limit = 0.2); 72 void test_accuracy(const float *expected, const float *result, unsigned num_values, double absolute_error_limit, double relative_error_limit, double local_relative_error_limit, double rms_limit); 73 74 // Convert an sRGB encoded value (0.0 to 1.0, inclusive) to linear light. 75 // Undefined for values outside 0.0..1.0. 76 double srgb_to_linear(double x); 77 78 // Convert a value in linear light (0.0 to 1.0, inclusive) to sRGB. 79 // Undefined for values outside 0.0..1.0. 80 double linear_to_srgb(double x); 81 82 // A RAII class to pretend temporarily that we don't support compute shaders 83 // even if we do. Useful for testing or benchmarking the fragment shader path 84 // also on systems that support compute shaders. 85 class DisableComputeShadersTemporarily 86 { 87 public: 88 // If disable_compute_shaders is false, this class effectively does nothing. 89 // Otherwise, sets movit_compute_shaders_supported unconditionally to false. 90 DisableComputeShadersTemporarily(bool disable_compute_shaders); 91 92 // Restore the old value of movit_compute_shaders_supported. 93 ~DisableComputeShadersTemporarily(); 94 95 // Whether the current test should be skipped due to lack of compute shaders 96 // (ie., disable_compute_shaders was _false_, but the system does not support 97 // compute shaders). Will also output a message to stderr if so. 98 bool should_skip(); 99 100 #ifdef HAVE_BENCHMARK 101 // Same, but outputs a message to the benchmark instead of to stderr. 102 bool should_skip(benchmark::State *benchmark_state); 103 #endif 104 active()105 bool active() const { return disable_compute_shaders; } 106 107 private: 108 bool disable_compute_shaders, saved_compute_shaders_supported; 109 }; 110 111 } // namespace movit 112 113 #endif // !defined(_MOVIT_TEST_UTIL_H) 114