X-Git-Url: https://git.sesse.net/?p=movit;a=blobdiff_plain;f=resample_effect.cpp;fp=resample_effect.cpp;h=802a8968a893482460988b910f2db707d68b692b;hp=b6da2e2aeea3be8f5605d6ec10525a37c082b152;hb=f8e5ddc082f2267198292ea9e53d4a8b45f7b3b1;hpb=d7def3f9e42e72566d7aedd52ffdeb5851da8314 diff --git a/resample_effect.cpp b/resample_effect.cpp index b6da2e2..802a896 100644 --- a/resample_effect.cpp +++ b/resample_effect.cpp @@ -502,7 +502,7 @@ void SingleResamplePassEffect::update_texture(GLuint glsl_program_num, const str assert(false); } - ScalingWeights weights = calculate_scaling_weights(src_size, dst_size, zoom, offset); + ScalingWeights weights = calculate_bilinear_scaling_weights(src_size, dst_size, zoom, offset); src_bilinear_samples = weights.src_bilinear_samples; num_loops = weights.num_loops; slice_height = 1.0f / weights.num_loops; @@ -529,6 +529,8 @@ void SingleResamplePassEffect::update_texture(GLuint glsl_program_num, const str tex.update(weights.src_bilinear_samples, weights.dst_samples, internal_format, GL_RG, type, pixels); } +namespace { + ScalingWeights calculate_scaling_weights(unsigned src_size, unsigned dst_size, float zoom, float offset) { // Only needed if run from outside ResampleEffect. @@ -627,16 +629,33 @@ ScalingWeights calculate_scaling_weights(unsigned src_size, unsigned dst_size, f } } + ScalingWeights ret; + ret.src_bilinear_samples = src_samples; + ret.dst_samples = dst_samples; + ret.num_loops = num_loops; + ret.bilinear_weights_fp16 = nullptr; + ret.bilinear_weights_fp32 = move(weights); + return ret; +} + +} // namespace + +ScalingWeights calculate_bilinear_scaling_weights(unsigned src_size, unsigned dst_size, float zoom, float offset) +{ + ScalingWeights ret = calculate_scaling_weights(src_size, dst_size, zoom, offset); + unique_ptr[]> weights = move(ret.bilinear_weights_fp32); + const int src_samples = ret.src_bilinear_samples; + // Now make use of the bilinear filtering in the GPU to reduce the number of samples // we need to make. Try fp16 first; if it's not accurate enough, we go to fp32. // Our tolerance level for total error is a bit higher than the one for invididual // samples, since one would assume overall errors in the shape don't matter as much. const float max_error = 2.0f / (255.0f * 255.0f); unique_ptr[]> bilinear_weights_fp16; - int src_bilinear_samples = combine_many_samples(weights.get(), src_size, src_samples, dst_samples, &bilinear_weights_fp16); + int src_bilinear_samples = combine_many_samples(weights.get(), src_size, src_samples, ret.dst_samples, &bilinear_weights_fp16); unique_ptr[]> bilinear_weights_fp32 = nullptr; double max_sum_sq_error_fp16 = 0.0; - for (unsigned y = 0; y < dst_samples; ++y) { + for (unsigned y = 0; y < ret.dst_samples; ++y) { double sum_sq_error_fp16 = compute_sum_sq_error( weights.get() + y * src_samples, src_samples, bilinear_weights_fp16.get() + y * src_bilinear_samples, src_bilinear_samples, @@ -649,13 +668,10 @@ ScalingWeights calculate_scaling_weights(unsigned src_size, unsigned dst_size, f if (max_sum_sq_error_fp16 > max_error) { bilinear_weights_fp16.reset(); - src_bilinear_samples = combine_many_samples(weights.get(), src_size, src_samples, dst_samples, &bilinear_weights_fp32); + src_bilinear_samples = combine_many_samples(weights.get(), src_size, src_samples, ret.dst_samples, &bilinear_weights_fp32); } - ScalingWeights ret; ret.src_bilinear_samples = src_bilinear_samples; - ret.dst_samples = dst_samples; - ret.num_loops = num_loops; ret.bilinear_weights_fp16 = move(bilinear_weights_fp16); ret.bilinear_weights_fp32 = move(bilinear_weights_fp32); return ret;