+ ScalingWeights weights = calculate_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;
+
+ // Encode as a two-component texture. Note the GL_REPEAT.
+ glActiveTexture(GL_TEXTURE0 + *sampler_num);
+ check_error();
+ glBindTexture(GL_TEXTURE_2D, texnum);
+ check_error();
+ if (last_texture_width == -1) {
+ // Need to set this state the first time.
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ check_error();
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ check_error();
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ check_error();
+ }
+
+ GLenum type, internal_format;
+ void *pixels;
+ assert((weights.bilinear_weights_fp16 == nullptr) != (weights.bilinear_weights_fp32 == nullptr));
+ if (weights.bilinear_weights_fp32 != nullptr) {
+ type = GL_FLOAT;
+ internal_format = GL_RG32F;
+ pixels = weights.bilinear_weights_fp32.get();
+ } else {
+ type = GL_HALF_FLOAT;
+ internal_format = GL_RG16F;
+ pixels = weights.bilinear_weights_fp16.get();
+ }
+
+ if (int(weights.src_bilinear_samples) == last_texture_width &&
+ int(weights.dst_samples) == last_texture_height &&
+ internal_format == last_texture_internal_format) {
+ // Texture dimensions and type are unchanged; it is more efficient
+ // to just update it rather than making an entirely new texture.
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, weights.src_bilinear_samples, weights.dst_samples, GL_RG, type, pixels);
+ } else {
+ glTexImage2D(GL_TEXTURE_2D, 0, internal_format, weights.src_bilinear_samples, weights.dst_samples, 0, GL_RG, type, pixels);
+ last_texture_width = weights.src_bilinear_samples;
+ last_texture_height = weights.dst_samples;
+ last_texture_internal_format = internal_format;
+ }
+ check_error();
+}
+
+ScalingWeights calculate_scaling_weights(unsigned src_size, unsigned dst_size, float zoom, float offset)
+{
+ if (!lanczos_table_init_done) {
+ // Only needed if run from outside ResampleEffect.
+ init_lanczos_table();
+ }
+