From 313b538bc6673039a1f3b5297c06bb60bace0ac8 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Sat, 28 Jul 2018 16:43:51 +0200 Subject: [PATCH] Split texture pooling out from DISComputeFlow into its own class. --- flow.cpp | 91 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 48 insertions(+), 43 deletions(-) diff --git a/flow.cpp b/flow.cpp index fe84351..e6347dc 100644 --- a/flow.cpp +++ b/flow.cpp @@ -1008,6 +1008,21 @@ private: bool ended = false; }; +class TexturePool { +public: + GLuint get_texture(GLenum format, GLuint width, GLuint height); + void release_texture(GLuint tex_num); + +private: + struct Texture { + GLuint tex_num; + GLenum format; + GLuint width, height; + bool in_use = false; + }; + vector textures; +}; + class DISComputeFlow { public: DISComputeFlow(int width, int height); @@ -1015,11 +1030,15 @@ public: // Returns a texture that must be released with release_texture() // after use. GLuint exec(GLuint tex0, GLuint tex1); - void release_texture(GLuint tex); + + void release_texture(GLuint tex) { + pool.release_texture(tex); + } private: int width, height; GLuint initial_flow_tex; + TexturePool pool; // The various passes. Sobel sobel; @@ -1032,16 +1051,6 @@ private: SOR sor; AddBaseFlow add_base_flow; ResizeFlow resize_flow; - - struct Texture { - GLuint tex_num; - GLenum format; - GLuint width, height; - bool in_use = false; - }; - vector textures; - - GLuint get_texture(GLenum format, GLuint width, GLuint height); }; DISComputeFlow::DISComputeFlow(int width, int height) @@ -1080,10 +1089,6 @@ DISComputeFlow::DISComputeFlow(int width, int height) GLuint DISComputeFlow::exec(GLuint tex0, GLuint tex1) { - for (const Texture &tex : textures) { - assert(!tex.in_use); - } - int prev_level_width = 1, prev_level_height = 1; GLuint prev_level_flow_tex = initial_flow_tex; @@ -1117,7 +1122,7 @@ GLuint DISComputeFlow::exec(GLuint tex0, GLuint tex1) // Create a new texture; we could be fancy and render use a multi-level // texture, but meh. - GLuint grad0_tex = get_texture(GL_RG16F, level_width, level_height); + GLuint grad0_tex = pool.get_texture(GL_RG16F, level_width, level_height); // Find the derivative. { @@ -1129,19 +1134,19 @@ GLuint DISComputeFlow::exec(GLuint tex0, GLuint tex1) // level (sampled bilinearly; no fancy tricks) as a guide, then search from there. // Create an output flow texture. - GLuint flow_out_tex = get_texture(GL_RGB16F, width_patches, height_patches); + GLuint flow_out_tex = pool.get_texture(GL_RGB16F, width_patches, height_patches); // And draw. { ScopedTimer timer("Motion search", &level_timer); motion_search.exec(tex0_view, tex1_view, grad0_tex, prev_level_flow_tex, flow_out_tex, level_width, level_height, prev_level_width, prev_level_height, width_patches, height_patches); } - release_texture(grad0_tex); + pool.release_texture(grad0_tex); // Densification. // Set up an output texture (initially zero). - GLuint dense_flow_tex = get_texture(GL_RGB16F, level_width, level_height); + GLuint dense_flow_tex = pool.get_texture(GL_RGB16F, level_width, level_height); glClearTexImage(dense_flow_tex, 0, GL_RGB, GL_FLOAT, nullptr); // And draw. @@ -1149,7 +1154,7 @@ GLuint DISComputeFlow::exec(GLuint tex0, GLuint tex1) ScopedTimer timer("Densification", &level_timer); densify.exec(tex0_view, tex1_view, flow_out_tex, dense_flow_tex, level_width, level_height, width_patches, height_patches); } - release_texture(flow_out_tex); + pool.release_texture(flow_out_tex); // Everything below here in the loop belongs to variational refinement. ScopedTimer varref_timer("Variational refinement", &level_timer); @@ -1161,14 +1166,14 @@ GLuint DISComputeFlow::exec(GLuint tex0, GLuint tex1) // in pixels, not 0..1 normalized OpenGL texture coordinates. // This is because variational refinement depends so heavily on derivatives, // which are measured in intensity levels per pixel. - GLuint I_tex = get_texture(GL_R16F, level_width, level_height); - GLuint I_t_tex = get_texture(GL_R16F, level_width, level_height); - GLuint base_flow_tex = get_texture(GL_RG16F, level_width, level_height); + GLuint I_tex = pool.get_texture(GL_R16F, level_width, level_height); + GLuint I_t_tex = pool.get_texture(GL_R16F, level_width, level_height); + GLuint base_flow_tex = pool.get_texture(GL_RG16F, level_width, level_height); { ScopedTimer timer("Prewarping", &varref_timer); prewarp.exec(tex0_view, tex1_view, dense_flow_tex, I_tex, I_t_tex, base_flow_tex, level_width, level_height); } - release_texture(dense_flow_tex); + pool.release_texture(dense_flow_tex); glDeleteTextures(1, &tex0_view); glDeleteTextures(1, &tex1_view); @@ -1177,26 +1182,26 @@ GLuint DISComputeFlow::exec(GLuint tex0, GLuint tex1) // textures overall, since sampling from the L1 cache is cheap. // (TODO: Verify that this is indeed faster than making separate // double-derivative textures.) - GLuint I_x_y_tex = get_texture(GL_RG16F, level_width, level_height); - GLuint beta_0_tex = get_texture(GL_R16F, level_width, level_height); + GLuint I_x_y_tex = pool.get_texture(GL_RG16F, level_width, level_height); + GLuint beta_0_tex = pool.get_texture(GL_R16F, level_width, level_height); { ScopedTimer timer("First derivatives", &varref_timer); derivatives.exec(I_tex, I_x_y_tex, beta_0_tex, level_width, level_height); } - release_texture(I_tex); + pool.release_texture(I_tex); // We need somewhere to store du and dv (the flow increment, relative // to the non-refined base flow u0 and v0). It starts at zero. - GLuint du_dv_tex = get_texture(GL_RG16F, level_width, level_height); + GLuint du_dv_tex = pool.get_texture(GL_RG16F, level_width, level_height); glClearTexImage(du_dv_tex, 0, GL_RG, GL_FLOAT, nullptr); // And for smoothness. - GLuint smoothness_x_tex = get_texture(GL_R16F, level_width, level_height); - GLuint smoothness_y_tex = get_texture(GL_R16F, level_width, level_height); + GLuint smoothness_x_tex = pool.get_texture(GL_R16F, level_width, level_height); + GLuint smoothness_y_tex = pool.get_texture(GL_R16F, level_width, level_height); // And finally for the equation set. See SetupEquations for // the storage format. - GLuint equation_tex = get_texture(GL_RGBA32UI, level_width, level_height); + GLuint equation_tex = pool.get_texture(GL_RGBA32UI, level_width, level_height); for (int outer_idx = 0; outer_idx < level + 1; ++outer_idx) { // Calculate the smoothness terms between the neighboring pixels, @@ -1220,12 +1225,12 @@ GLuint DISComputeFlow::exec(GLuint tex0, GLuint tex1) } } - release_texture(I_t_tex); - release_texture(I_x_y_tex); - release_texture(beta_0_tex); - release_texture(smoothness_x_tex); - release_texture(smoothness_y_tex); - release_texture(equation_tex); + pool.release_texture(I_t_tex); + pool.release_texture(I_x_y_tex); + pool.release_texture(beta_0_tex); + pool.release_texture(smoothness_x_tex); + pool.release_texture(smoothness_y_tex); + pool.release_texture(equation_tex); // Add the differential flow found by the variational refinement to the base flow, // giving the final flow estimate for this level. @@ -1237,10 +1242,10 @@ GLuint DISComputeFlow::exec(GLuint tex0, GLuint tex1) ScopedTimer timer("Add differential flow", &varref_timer); add_base_flow.exec(base_flow_tex, du_dv_tex, level_width, level_height); } - release_texture(du_dv_tex); + pool.release_texture(du_dv_tex); if (prev_level_flow_tex != initial_flow_tex) { - release_texture(prev_level_flow_tex); + pool.release_texture(prev_level_flow_tex); } prev_level_flow_tex = base_flow_tex; prev_level_width = level_width; @@ -1254,14 +1259,14 @@ GLuint DISComputeFlow::exec(GLuint tex0, GLuint tex1) if (finest_level == 0) { return prev_level_flow_tex; } else { - GLuint final_tex = get_texture(GL_RG16F, width, height); + GLuint final_tex = pool.get_texture(GL_RG16F, width, height); resize_flow.exec(prev_level_flow_tex, final_tex, prev_level_width, prev_level_height, width, height); - release_texture(prev_level_flow_tex); + pool.release_texture(prev_level_flow_tex); return final_tex; } } -GLuint DISComputeFlow::get_texture(GLenum format, GLuint width, GLuint height) +GLuint TexturePool::get_texture(GLenum format, GLuint width, GLuint height) { for (Texture &tex : textures) { if (!tex.in_use && tex.format == format && @@ -1282,7 +1287,7 @@ GLuint DISComputeFlow::get_texture(GLenum format, GLuint width, GLuint height) return tex.tex_num; } -void DISComputeFlow::release_texture(GLuint tex_num) +void TexturePool::release_texture(GLuint tex_num) { for (Texture &tex : textures) { if (tex.tex_num == tex_num) { -- 2.39.2