Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions src/libslic3r/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1591,11 +1591,26 @@ size_t available_physical_memory()
return (size_t) status.ullAvailPhys;

#elif defined(__linux__)
struct sysinfo info;
if (sysinfo(&info) == 0) {
return info.freeram * info.mem_unit;
// Prefer MemAvailable (free + reclaimable page/buffer cache) from
// /proc/meminfo. sysinfo().freeram is only MemFree, which Linux keeps
// low by design (idle RAM is used for cache), so it grossly understates
// usable memory and must not be treated as "available".
if (FILE* mi = fopen("/proc/meminfo", "r")) {
char line[256];
unsigned long long kb = 0;
bool found = false;
while (fgets(line, sizeof(line), mi) != nullptr) {
if (sscanf(line, "MemAvailable: %llu kB", &kb) == 1) { found = true; break; }
}
fclose(mi);
if (found)
return (size_t)kb * (size_t)1024;
}
return 0L;
// Fallback for kernels < 3.14 without MemAvailable: free + buffers.
struct sysinfo info;
if (sysinfo(&info) == 0)
return (size_t)(info.freeram + info.bufferram) * (size_t)info.mem_unit;
return 0L;
#elif defined(__APPLE__)
int mib[2] = {CTL_HW, HW_MEMSIZE};
uint64_t memsize;
Expand Down
20 changes: 6 additions & 14 deletions src/slic3r/GUI/GCodeRenderer/AdvancedRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -748,20 +748,12 @@ namespace Slic3r
// Import gcode file, preview using normal mode (no lite mode)
bool is_lite_mode_cfg = (wxGetApp().app_config->get_bool("gcode_preview_lite_mode") && (!m_only_gcode_in_preview));

// Auto enable lite mode on Linux if memory is tight or preview is huge.
#if defined(__linux__)
{
size_t avail_bytes = Slic3r::available_physical_memory();
size_t total_bytes = Slic3r::total_physical_memory();
const size_t moves_count_local = gcode_result.moves.size();
const size_t avail_threshold_bytes = size_t(2) * size_t(1024) * size_t(1024) * size_t(1024); // 2 GB
const bool low_available = (avail_bytes > 0 && avail_bytes < avail_threshold_bytes);
const bool low_ratio = (total_bytes > 0 && avail_bytes > 0 && (double) avail_bytes / (double) total_bytes < 0.125);
const bool huge_preview = (moves_count_local > 2000000);
if (!m_only_gcode_in_preview && (low_available || low_ratio || huge_preview))
is_lite_mode_cfg = true;
}
#endif
// NOTE (#512): Removed the Linux-only auto-enable-lite-mode heuristic.
// It force-enabled lite mode against the user's explicit
// gcode_preview_lite_mode=false setting, and tripped on broken memory
// readings (available/total reported as 0 on some systems), permanently
// hiding infill in the preview on Linux. Lite mode is now strictly
// driven by the gcode_preview_lite_mode config value above.

const bool is_lite_mode = m_is_lite_mode = is_lite_mode_cfg;

Expand Down
30 changes: 5 additions & 25 deletions src/slic3r/GUI/GUI_Preview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -742,31 +742,11 @@ void Preview::load_print_as_fff(bool keep_z_range, bool only_gcode)
// import gcode file, preview using normal mode (no lite mode)
bool is_lite_mode = wxGetApp().app_config->get_bool("gcode_preview_lite_mode") && (!only_gcode);

// Auto enable lite mode on Linux if memory is tight or preview is huge
// This does NOT affect Windows and does not persist the setting.
#if defined(__linux__)
{
size_t avail_bytes = Slic3r::available_physical_memory();
size_t total_bytes = Slic3r::total_physical_memory();
const size_t moves_count = m_gcode_result ? m_gcode_result->moves.size() : 0;

// Heuristics:
// - Consider memory tight if available < 2 GB or available < 12.5% of total.
// - Consider preview huge if moves exceed 2 million.
const size_t avail_threshold_bytes = size_t(2) * size_t(1024) * size_t(1024) * size_t(1024); // 2 GB
const bool low_available = (avail_bytes > 0 && avail_bytes < avail_threshold_bytes);
const bool low_ratio = (total_bytes > 0 && avail_bytes > 0 && (double)avail_bytes / (double)total_bytes < 0.125);
const bool huge_preview = (moves_count > 2000000);

if (!only_gcode && (low_available || low_ratio || huge_preview)) {
is_lite_mode = true;
// Also enable shell-only surface rendering to further reduce load.
if (m_gcode_result) {
m_gcode_result->all_surface_with_shell = true;
}
}
}
#endif
// NOTE (#512): removed the Linux auto-enable-lite-mode heuristic
// here (mirrors the advanced renderer). It overrode the user's
// explicit gcode_preview_lite_mode setting and, because
// available_physical_memory() reported MemFree, fired on almost
// every Linux machine. Lite mode now follows the config value above.
std::vector<std::pair<EMoveType, size_t>> changed_tmp;
GCodeProcessorResult* tmp_result = nullptr;
if (is_lite_mode) {
Expand Down