From d50a326ca7d25a0ac3147bc2e0217e4b387ddd09 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 29 Feb 2016 19:49:26 +0100 Subject: [PATCH] Fix silly multiple uncompress&recompress when generating mips for compressed texture --- panda/src/egg2pg/eggLoader.cxx | 5 +++++ panda/src/gobj/config_gobj.cxx | 7 ------- panda/src/gobj/config_gobj.h | 1 - panda/src/gobj/texture.I | 7 +++++-- panda/src/gobj/texture.cxx | 29 +++++++++++++++++++++-------- panda/src/gobj/texture.h | 2 +- panda/src/putil/config_util.cxx | 7 +++++++ panda/src/putil/config_util.h | 1 + panda/src/putil/loaderOptions.cxx | 8 ++++++++ panda/src/putil/loaderOptions.h | 1 + 10 files changed, 49 insertions(+), 19 deletions(-) diff --git a/panda/src/egg2pg/eggLoader.cxx b/panda/src/egg2pg/eggLoader.cxx index ad309e0174..feeab556c5 100644 --- a/panda/src/egg2pg/eggLoader.cxx +++ b/panda/src/egg2pg/eggLoader.cxx @@ -950,6 +950,11 @@ load_texture(TextureDef &def, EggTexture *egg_tex) { } } + // Allow the texture loader to pre-compress the texture. + if (egg_tex->get_compression_mode() == EggTexture::CM_on) { + options.set_texture_flags(options.get_texture_flags() | LoaderOptions::TF_allow_compression); + } + PT(Texture) tex; switch (egg_tex->get_texture_type()) { case EggTexture::TT_unspecified: diff --git a/panda/src/gobj/config_gobj.cxx b/panda/src/gobj/config_gobj.cxx index f753126f19..4df77f0527 100644 --- a/panda/src/gobj/config_gobj.cxx +++ b/panda/src/gobj/config_gobj.cxx @@ -112,13 +112,6 @@ ConfigVariableBool keep_texture_ram "texture image from disk; but it will consume memory somewhat " "wastefully.")); -ConfigVariableBool compressed_textures -("compressed-textures", false, - PRC_DESC("Set this to true to compress textures as they are loaded into " - "texture memory, if the driver supports this. Specifically, this " - "changes the meaning of set_compression(Texture::CM_default) to " - "Texture::CM_on.")); - ConfigVariableBool driver_compress_textures ("driver-compress-textures", false, PRC_DESC("Set this true to ask the graphics driver to compress textures, " diff --git a/panda/src/gobj/config_gobj.h b/panda/src/gobj/config_gobj.h index e9780873ea..d3b651d3d4 100644 --- a/panda/src/gobj/config_gobj.h +++ b/panda/src/gobj/config_gobj.h @@ -36,7 +36,6 @@ extern EXPCL_PANDA_GOBJ ConfigVariableList exclude_texture_scale; extern EXPCL_PANDA_GOBJ ConfigVariableBool keep_texture_ram; -extern EXPCL_PANDA_GOBJ ConfigVariableBool compressed_textures; extern EXPCL_PANDA_GOBJ ConfigVariableBool driver_compress_textures; extern EXPCL_PANDA_GOBJ ConfigVariableBool driver_generate_mipmaps; extern EXPCL_PANDA_GOBJ ConfigVariableBool vertex_buffers; diff --git a/panda/src/gobj/texture.I b/panda/src/gobj/texture.I index eefbb090fe..534b7aad00 100644 --- a/panda/src/gobj/texture.I +++ b/panda/src/gobj/texture.I @@ -1678,9 +1678,12 @@ clear_ram_mipmap_images() { */ INLINE void Texture:: generate_ram_mipmap_images() { - CDWriter cdata(_cycler, unlocked_ensure_ram_image(false)); + // Don't use unlocked_ensure_ram_image here, because + // do_generate_ram_mipmap_images will want to decompress and recompress the + // image itself. + CDWriter cdata(_cycler, false); cdata->inc_image_modified(); - do_generate_ram_mipmap_images(cdata); + do_generate_ram_mipmap_images(cdata, true); } /** diff --git a/panda/src/gobj/texture.cxx b/panda/src/gobj/texture.cxx index 4b3ac328e9..0d0054fed7 100644 --- a/panda/src/gobj/texture.cxx +++ b/panda/src/gobj/texture.cxx @@ -2708,7 +2708,8 @@ do_read(CData *cdata, const Filename &fullpath, const Filename &alpha_fullpath, // If we intend to keep the ram image around, consider compressing it // etc. bool generate_mipmaps = ((options.get_texture_flags() & LoaderOptions::TF_generate_mipmaps) != 0); - do_consider_auto_process_ram_image(cdata, generate_mipmaps || uses_mipmaps(), true); + bool allow_compression = ((options.get_texture_flags() & LoaderOptions::TF_allow_compression) != 0); + do_consider_auto_process_ram_image(cdata, generate_mipmaps || uses_mipmaps(), allow_compression); } } @@ -4277,7 +4278,12 @@ do_reload_ram_image(CData *cdata, bool allow_compression) { int orig_num_components = cdata->_num_components; LoaderOptions options; - options.set_texture_flags(LoaderOptions::TF_preload); + if (allow_compression) { + options.set_texture_flags(LoaderOptions::TF_preload | + LoaderOptions::TF_allow_compression); + } else { + options.set_texture_flags(LoaderOptions::TF_preload); + } do_read(cdata, cdata->_fullpath, cdata->_alpha_fullpath, cdata->_primary_file_num_channels, cdata->_alpha_file_channel, z, n, cdata->_has_read_pages, cdata->_has_read_mipmaps, options, NULL); @@ -4618,7 +4624,7 @@ do_consider_auto_process_ram_image(CData *cdata, bool generate_mipmaps, if (generate_mipmaps && !driver_generate_mipmaps && cdata->_ram_images.size() == 1) { - do_generate_ram_mipmap_images(cdata); + do_generate_ram_mipmap_images(cdata, false); modified = true; } @@ -4725,7 +4731,7 @@ do_compress_ram_image(CData *cdata, Texture::CompressionMode compression, if (!do_has_all_ram_mipmap_images(cdata)) { // If we're about to compress the RAM image, we should ensure that we // have all of the mipmap levels first. - do_generate_ram_mipmap_images(cdata); + do_generate_ram_mipmap_images(cdata, false); } RamImages compressed_ram_images; @@ -6334,10 +6340,12 @@ do_clear_ram_mipmap_images(CData *cdata) { } /** - * + * Generates the RAM mipmap images for this texture, first uncompressing it as + * required. Will recompress the image if it was originally compressed, + * unless allow_recompress is true. */ void Texture:: -do_generate_ram_mipmap_images(CData *cdata) { +do_generate_ram_mipmap_images(CData *cdata, bool allow_recompress) { nassertv(do_has_ram_image(cdata)); if (do_get_expected_num_mipmap_levels(cdata) == 1) { @@ -6399,7 +6407,7 @@ do_generate_ram_mipmap_images(CData *cdata) { } } - if (orig_compression_mode != CM_off) { + if (orig_compression_mode != CM_off && allow_recompress) { // Now attempt to recompress the mipmap images according to the original // compression mode. We don't need to bother compressing the first image // (it was already compressed, after all), so temporarily remove it from @@ -6418,6 +6426,11 @@ do_generate_ram_mipmap_images(CData *cdata) { bool success = do_compress_ram_image(cdata, orig_compression_mode, QL_default, NULL); // Now restore the toplevel image. if (success) { + if (gobj_cat.is_debug()) { + gobj_cat.debug() + << "Compressed " << get_name() << " generated mipmaps with " + << cdata->_ram_image_compression << "\n"; + } cdata->_ram_images.insert(cdata->_ram_images.begin(), orig_compressed_image); } else { cdata->_ram_images.insert(cdata->_ram_images.begin(), uncompressed_image); @@ -8255,7 +8268,7 @@ do_squish(CData *cdata, Texture::CompressionMode compression, int squish_flags) if (!do_has_all_ram_mipmap_images(cdata)) { // If we're about to compress the RAM image, we should ensure that we have // all of the mipmap levels first. - do_generate_ram_mipmap_images(cdata); + do_generate_ram_mipmap_images(cdata, false); } RamImages compressed_ram_images; diff --git a/panda/src/gobj/texture.h b/panda/src/gobj/texture.h index fa64b0fa42..15f465ac4d 100644 --- a/panda/src/gobj/texture.h +++ b/panda/src/gobj/texture.h @@ -697,7 +697,7 @@ protected: INLINE void do_clear_ram_image(CData *cdata); void do_clear_simple_ram_image(CData *cdata); void do_clear_ram_mipmap_images(CData *cdata); - void do_generate_ram_mipmap_images(CData *cdata); + void do_generate_ram_mipmap_images(CData *cdata, bool allow_recompress); void do_set_pad_size(CData *cdata, int x, int y, int z); virtual bool do_can_reload(const CData *cdata) const; bool do_reload(CData *cdata); diff --git a/panda/src/putil/config_util.cxx b/panda/src/putil/config_util.cxx index 25277a436e..e12d66d066 100644 --- a/panda/src/putil/config_util.cxx +++ b/panda/src/putil/config_util.cxx @@ -143,6 +143,13 @@ ConfigVariableBool preload_simple_textures "in a sub-thread. It's not generally necessary if you are " "loading bam files that were generated via egg2bam.")); +ConfigVariableBool compressed_textures +("compressed-textures", false, + PRC_DESC("Set this to true to compress textures as they are loaded into " + "texture memory, if the driver supports this. Specifically, this " + "changes the meaning of set_compression(Texture::CM_default) to " + "Texture::CM_on.")); + ConfigVariableBool cache_check_timestamps ("cache-check-timestamps", true, PRC_DESC("Set this true to check the timestamps on disk (when possible) " diff --git a/panda/src/putil/config_util.h b/panda/src/putil/config_util.h index 1127d35fe4..5fb669d86c 100644 --- a/panda/src/putil/config_util.h +++ b/panda/src/putil/config_util.h @@ -46,6 +46,7 @@ extern ConfigVariableDouble sleep_precision; extern EXPCL_PANDA_PUTIL ConfigVariableBool preload_textures; extern EXPCL_PANDA_PUTIL ConfigVariableBool preload_simple_textures; +extern EXPCL_PANDA_PUTIL ConfigVariableBool compressed_textures; extern EXPCL_PANDA_PUTIL ConfigVariableBool cache_check_timestamps; extern EXPCL_PANDA_PUTIL void init_libputil(); diff --git a/panda/src/putil/loaderOptions.cxx b/panda/src/putil/loaderOptions.cxx index 5743deaa63..61aeb4f5d1 100644 --- a/panda/src/putil/loaderOptions.cxx +++ b/panda/src/putil/loaderOptions.cxx @@ -28,12 +28,16 @@ LoaderOptions(int flags) : // Shadowing the variables in config_util for static init ordering issues. static ConfigVariableBool *preload_textures; static ConfigVariableBool *preload_simple_textures; + static ConfigVariableBool *compressed_textures; if (preload_textures == NULL) { preload_textures = new ConfigVariableBool("preload-textures", true); } if (preload_simple_textures == NULL) { preload_simple_textures = new ConfigVariableBool("preload-simple-textures", false); } + if (compressed_textures == NULL) { + compressed_textures = new ConfigVariableBool("compressed-textures", false); + } if (*preload_textures) { _texture_flags |= TF_preload; @@ -41,6 +45,9 @@ LoaderOptions(int flags) : if (*preload_simple_textures) { _texture_flags |= TF_preload_simple; } + if (*compressed_textures) { + _texture_flags |= TF_allow_compression; + } } /** @@ -77,6 +84,7 @@ output(ostream &out) const { write_texture_flag(out, sep, "TF_preload_simple", TF_preload_simple); write_texture_flag(out, sep, "TF_allow_1d", TF_allow_1d); write_texture_flag(out, sep, "TF_generate_mipmaps", TF_generate_mipmaps); + write_texture_flag(out, sep, "TF_allow_compression", TF_allow_compression); if (sep.empty()) { out << "0"; } diff --git a/panda/src/putil/loaderOptions.h b/panda/src/putil/loaderOptions.h index 3db6f81f5a..50c73f983e 100644 --- a/panda/src/putil/loaderOptions.h +++ b/panda/src/putil/loaderOptions.h @@ -45,6 +45,7 @@ PUBLISHED: TF_multiview = 0x0040, // Load a multiview texture in pages TF_integer = 0x0080, // Load as an integer (RGB) texture TF_float = 0x0100, // Load as a floating-point (depth) texture + TF_allow_compression = 0x0200, // Consider compressing RAM image }; LoaderOptions(int flags = LF_search | LF_report_errors);