diff --git a/src/libslic3r/TextureDisplacement.cpp b/src/libslic3r/TextureDisplacement.cpp index ab63a75c70..26e8726a72 100644 --- a/src/libslic3r/TextureDisplacement.cpp +++ b/src/libslic3r/TextureDisplacement.cpp @@ -283,7 +283,7 @@ bool height_texture_has_color(const TextureDisplacementLayer &layer) return decode_height_texture(layer).has_color(); } -DecodedHeightTexture decode_height_texture(const TextureDisplacementLayer &layer) +DecodedHeightTexture decode_height_texture(const TextureDisplacementLayer &layer, bool keep_decoded) { DecodedHeightTexture result; if (layer.empty()) @@ -351,13 +351,15 @@ DecodedHeightTexture decode_height_texture(const TextureDisplacementLayer &layer } } - std::lock_guard lock(g_decoded_texture_cache.mutex); - // Opportunistically drop entries for image_data that no longer exists anywhere, so the - // cache doesn't grow without bound across many add/remove-texture cycles in a long session. - auto &entries = g_decoded_texture_cache.entries; - for (auto it = entries.begin(); it != entries.end();) - it = it->second.first.expired() ? entries.erase(it) : std::next(it); - entries[key] = { std::weak_ptr>(layer.image_data), result }; + if (keep_decoded) { + std::lock_guard lock(g_decoded_texture_cache.mutex); + // Opportunistically drop entries for image_data that no longer exists anywhere, so the + // cache doesn't grow without bound across many add/remove-texture cycles in a long session. + auto &entries = g_decoded_texture_cache.entries; + for (auto it = entries.begin(); it != entries.end();) + it = it->second.first.expired() ? entries.erase(it) : std::next(it); + entries[key] = { std::weak_ptr>(layer.image_data), result }; + } } // The image-adjustment panel's live edits, on top of the decode and before the smoothing. Before, diff --git a/src/libslic3r/TextureDisplacement.hpp b/src/libslic3r/TextureDisplacement.hpp index 6bd5d1ea33..919dfad654 100644 --- a/src/libslic3r/TextureDisplacement.hpp +++ b/src/libslic3r/TextureDisplacement.hpp @@ -599,8 +599,9 @@ DecodedHeightTexture downscale_height_texture(const DecodedHeightTexture &src, i // colour PNGs are accepted; for a colour source the height is its luminance, using the same // coefficients wxImage::ConvertToGreyscale() uses, so a texture imported as colour displaces exactly // as it did when the importer flattened it to grey on the way in. Returns an empty -// DecodedHeightTexture if image_data is empty or is not a PNG at all. -DecodedHeightTexture decode_height_texture(const TextureDisplacementLayer &layer); +// DecodedHeightTexture if image_data is empty or is not a PNG at all. keep_decoded = false leaves the +// result out of the decode cache, for one-off reads such as a picker thumbnail that must not hold full-size pixels. +DecodedHeightTexture decode_height_texture(const TextureDisplacementLayer &layer, bool keep_decoded = true); // decode_height_texture(layer).has_color(), answered from the decode cache rather than from a copy of the // texture - cheap enough to ask every frame. Smoothing does not change it, so the raw decode is what is read. diff --git a/src/slic3r/GUI/Gizmos/GLGizmoTextureDisplacement.cpp b/src/slic3r/GUI/Gizmos/GLGizmoTextureDisplacement.cpp index be1f72e520..646a23912a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoTextureDisplacement.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoTextureDisplacement.cpp @@ -4122,7 +4122,7 @@ const GLGizmoTextureDisplacement::LibraryTexture *GLGizmoTextureDisplacement::ge if (entry.image_data) { TextureDisplacementLayer probe; probe.image_data = entry.image_data; - entry.thumbnail = upload_height_thumbnail(decode_height_texture(probe)); + entry.thumbnail = upload_height_thumbnail(decode_height_texture(probe, /* keep_decoded */ false)); if (!entry.thumbnail) entry.image_data.reset(); // decoded to nothing usable - treat it as a failed load } else {