From: Steinar H. Gunderson Date: Wed, 22 Nov 2017 19:36:22 +0000 (+0100) Subject: Manage intermediate textures a bit more efficiently. X-Git-Tag: 1.6.0~41 X-Git-Url: https://git.sesse.net/?p=movit;a=commitdiff_plain;h=c2d60d500bbe8d8c987e312d2a2659ca432896d4 Manage intermediate textures a bit more efficiently. By holding on to them only for as long as we need to, we'll save some peak texture RAM, and _might_ in some situations get a bit less cache trashing. --- diff --git a/effect_chain.cpp b/effect_chain.cpp index a83a952..c9d746f 100644 --- a/effect_chain.cpp +++ b/effect_chain.cpp @@ -1882,9 +1882,18 @@ void EffectChain::render(GLuint dest_fbo, const vector &dest set generated_mipmaps; - // We choose the simplest option of having one texture per output, - // since otherwise this turns into an (albeit simple) register allocation problem. + // We keep one texture per output, but only for as long as we actually have any + // phases that need it as an input. (We don't make any effort to reorder phases + // to minimize the number of textures in play, as register allocation can be + // complicated and we rarely have much to gain, since our graphs are typically + // pretty linear.) map output_textures; + map ref_counts; + for (Phase *phase : phases) { + for (Phase *input : phase->inputs) { + ++ref_counts[input]; + } + } size_t num_phases = phases.size(); if (destinations.empty()) { @@ -1972,6 +1981,15 @@ void EffectChain::render(GLuint dest_fbo, const vector &dest if (do_phase_timing) { glEndQuery(GL_TIME_ELAPSED); } + + // Drop any input textures we don't need anymore. + for (Phase *input : phase->inputs) { + assert(ref_counts[input] > 0); + if (--ref_counts[input] == 0) { + resource_pool->release_2d_texture(output_textures[input]); + output_textures.erase(input); + } + } } for (const auto &phase_and_texnum : output_textures) {