From: Steinar H. Gunderson Date: Sun, 6 Sep 2015 22:10:48 +0000 (+0200) Subject: Minor optimization in ResampleEffect: Set less GL state. X-Git-Tag: 1.2.0~25 X-Git-Url: https://git.sesse.net/?p=movit;a=commitdiff_plain;h=c2ca57b71bf77244acc85aaccb2d6c360517c5a3 Minor optimization in ResampleEffect: Set less GL state. In particular, if we can avoid it, use glTexSubImage2D instead of glTexImage2D. This actually has a real effect, at least on Intel/Linux, where the drive seems to stall on some mappings. Of course, this only really helps for things like pans, not zooms. --- diff --git a/resample_effect.cpp b/resample_effect.cpp index 54eec86..0ec611a 100644 --- a/resample_effect.cpp +++ b/resample_effect.cpp @@ -380,7 +380,8 @@ SingleResamplePassEffect::SingleResamplePassEffect(ResampleEffect *parent) last_output_width(-1), last_output_height(-1), last_offset(0.0 / 0.0), // NaN. - last_zoom(0.0 / 0.0) // NaN. + last_zoom(0.0 / 0.0), // NaN. + last_texture_width(-1), last_texture_height(-1) { register_int("direction", (int *)&direction); register_int("input_width", &input_width); @@ -554,16 +555,39 @@ void SingleResamplePassEffect::update_texture(GLuint glsl_program_num, const str check_error(); glBindTexture(GL_TEXTURE_2D, texnum); check_error(); - 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(); + 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; if (fallback_to_fp32) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RG32F, src_bilinear_samples, dst_samples, 0, GL_RG, GL_FLOAT, bilinear_weights_fp32); + type = GL_FLOAT; + internal_format = GL_RG32F; + pixels = bilinear_weights_fp32; + } else { + type = GL_HALF_FLOAT; + internal_format = GL_RG16F; + pixels = bilinear_weights_fp16; + } + + if (int(src_bilinear_samples) == last_texture_width && + int(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, src_bilinear_samples, dst_samples, GL_RG, type, pixels); } else { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RG16F, src_bilinear_samples, dst_samples, 0, GL_RG, GL_HALF_FLOAT, bilinear_weights_fp16); + glTexImage2D(GL_TEXTURE_2D, 0, internal_format, src_bilinear_samples, dst_samples, 0, GL_RG, type, pixels); + last_texture_width = src_bilinear_samples; + last_texture_height = dst_samples; + last_texture_internal_format = internal_format; } check_error(); diff --git a/resample_effect.h b/resample_effect.h index 669d15b..73dfc21 100644 --- a/resample_effect.h +++ b/resample_effect.h @@ -109,6 +109,8 @@ private: float last_offset, last_zoom; int src_bilinear_samples, num_loops; float slice_height; + int last_texture_width, last_texture_height; + GLuint last_texture_internal_format; }; } // namespace movit