mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-18 13:10:54 +00:00
Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df80c9ae22 | ||
|
|
1ee0b730a1 | ||
|
|
72ba7a2b35 | ||
|
|
8160f64cae |
No files matched your search
@@ -574,7 +574,8 @@ DMABUF workaround and then branches on `GDK_BACKEND` (an `x11` prefix means the
|
||||
paths, when `/proc/driver/nvidia/version` exists and the linked WebKitGTK honours the switch (>= 2.44,
|
||||
`WebView::SupportsForceSharedMemory()`), it sets `WEBKIT_DMABUF_RENDERER_FORCE_SHM=1` and
|
||||
`WEBKIT_FORCE_DMABUF_RENDERER=1` (non-replacing): the proprietary driver cannot back WebKit's hardware
|
||||
DMABUF renderer. On the default path it forces `GDK_BACKEND=x11` when wx lacks EGL and `WAYLAND_DISPLAY`
|
||||
DMABUF renderer. On a hypervisor guest (`/proc/cpuinfo` `hypervisor` flag) and WebKitGTK >= 2.44 it sets
|
||||
`WEBKIT_DMABUF_RENDERER_FORCE_SHM=1` alone, since virtual GPUs cannot back the hardware path either. On the default path it forces `GDK_BACKEND=x11` when wx lacks EGL and `WAYLAND_DISPLAY`
|
||||
is set, and sets `WEBKIT_DISABLE_COMPOSITING_MODE=1` (non-replacing) inside that branch when the linked
|
||||
WebKitGTK is older than 2.42: a forced X11 backend in a Wayland session is the only default-path case
|
||||
that runs through XWayland, which `DISPLAY` and `WAYLAND_DISPLAY` alone do not tell you (a native
|
||||
|
||||
@@ -568,13 +568,18 @@ vue-resize workaround script and sets a persistent SQLite cookie store on the vi
|
||||
## WebKitGTK on Linux sessions
|
||||
|
||||
**Mechanism.** `CLI::run` (`src/OrcaSlicer.cpp`, under `#ifdef __WXGTK__`, before GTK initialises)
|
||||
sets the NVIDIA DMABUF workaround and then branches on `GDK_BACKEND`:
|
||||
sets the DMABUF workarounds and then branches on `GDK_BACKEND`:
|
||||
- **Both paths**, before the split: when `/proc/driver/nvidia/version` exists and the linked WebKitGTK
|
||||
honours the switch (>= 2.44, `WebView::SupportsForceSharedMemory()`), it sets
|
||||
`WEBKIT_DMABUF_RENDERER_FORCE_SHM=1` and `WEBKIT_FORCE_DMABUF_RENDERER=1` non-replacing. The
|
||||
proprietary driver cannot back WebKit's hardware DMABUF renderer, so the shared-memory transport keeps
|
||||
accelerated compositing instead of dropping it; `WEBKIT_FORCE_DMABUF_RENDERER` clears the
|
||||
Debian/Ubuntu/openSUSE `isNVIDIA()` early return, which otherwise returns before the FORCE_SHM check.
|
||||
- **Hypervisor guests**, same position: when `is_hypervisor_guest()` (the `hypervisor` flag in
|
||||
`/proc/cpuinfo`) and WebKitGTK >= 2.44, it sets `WEBKIT_DMABUF_RENDERER_FORCE_SHM=1` non-replacing.
|
||||
Virtual GPUs (VirtualBox VMSVGA, VMware, QEMU) cannot back the hardware DMABUF path either, and
|
||||
FORCE_SHM alone was confirmed to fix web views in VirtualBox; the `WEBKIT_FORCE_DMABUF_RENDERER` pair
|
||||
is not needed without the Debian `isNVIDIA()` patch. The flag is x86-only, so ARM guests are not covered.
|
||||
- **Default path** (`GDK_BACKEND` unset or not starting with `x11`): if wx lacks EGL (`!wxHAS_EGL`) and
|
||||
`WAYLAND_DISPLAY` is set, it forces `GDK_BACKEND=x11`, and in that same branch it sets
|
||||
`WEBKIT_DISABLE_COMPOSITING_MODE=1` non-replacing when the linked WebKitGTK predates 2.42
|
||||
@@ -590,9 +595,9 @@ Runtime backend detection elsewhere uses Orca's `is_running_on_wayland()` / `is_
|
||||
(see `references/platforms.md`), not these environment variables.
|
||||
|
||||
**Pitfall.**
|
||||
- **Rule:** On NVIDIA reach for `WEBKIT_DMABUF_RENDERER_FORCE_SHM` before
|
||||
`WEBKIT_DISABLE_COMPOSITING_MODE`. **Why:** the proprietary driver cannot back WebKit's hardware
|
||||
DMABUF renderer, leaving web views blank or slow; FORCE_SHM keeps accelerated compositing and only
|
||||
- **Rule:** On NVIDIA and hypervisor guests reach for `WEBKIT_DMABUF_RENDERER_FORCE_SHM` before
|
||||
`WEBKIT_DISABLE_COMPOSITING_MODE`. **Why:** the proprietary driver and virtual GPUs cannot back WebKit's
|
||||
hardware DMABUF renderer, leaving web views blank or slow; FORCE_SHM keeps accelerated compositing and only
|
||||
skips the hardware path, while disabling compositing drops it. Threaded scrolling is a separate,
|
||||
release-dependent default (off in 2.44/2.45, on from 2.46). `WEBKIT_DISABLE_DMABUF_RENDERER` is not a
|
||||
substitute — it is read first, leaves the transport set empty (no compositing from 2.44 on, where the
|
||||
|
||||
@@ -350,8 +350,11 @@ identity default and translates nothing. `NetworkAgent` forwards both to the liv
|
||||
comparison sites below reach them through `wxGetApp().getAgent()` and leave an id untranslated
|
||||
while no agent is live. Whole documents are Bambu's business alone:
|
||||
`BBLPrinterAgent::to_orca_payload` and `from_orca_payload` rewrite every string under
|
||||
`tray_info_idx`, `filament_id` or `filamentId` at any depth; text that does not parse, or carries
|
||||
none of those keys, comes back unchanged. The map is loaded once, lazily; a missing or malformed
|
||||
`tray_info_idx`, `filament_id`, `filamentId`, `cate` or `fila_id` at any depth; text that does not
|
||||
parse, or carries none of those keys, comes back unchanged. The last two are the H2C nozzle rack's:
|
||||
`cate` in the auto nozzle mapping request, `fila_id` in the rack status. A new Bambu message that
|
||||
carries a filament id under another key needs that key added to `filament_id_keys`, or the id
|
||||
crosses the boundary untranslated. The map is loaded once, lazily; a missing or malformed
|
||||
file degrades to identity with a log line rather than failing.
|
||||
|
||||
| Boundary | Where it translates |
|
||||
|
||||
@@ -1126,6 +1126,19 @@ static void load_downward_settings_list_from_config(std::string config_file, std
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __WXGTK__
|
||||
// Virtual GPUs (VirtualBox, VMware, QEMU) cannot back WebKit's hardware DMABUF renderer.
|
||||
static bool is_hypervisor_guest()
|
||||
{
|
||||
std::ifstream cpuinfo("/proc/cpuinfo");
|
||||
std::string line;
|
||||
while (std::getline(cpuinfo, line))
|
||||
if (boost::starts_with(line, "flags"))
|
||||
return line.find(" hypervisor") != std::string::npos;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
int CLI::run(int argc, char **argv)
|
||||
{
|
||||
// Mark the main thread for the debugger and for runtime checks.
|
||||
@@ -1176,6 +1189,9 @@ int CLI::run(int argc, char **argv)
|
||||
::setenv("WEBKIT_FORCE_DMABUF_RENDERER", "1", /* replace */ false);
|
||||
}
|
||||
|
||||
if (is_hypervisor_guest() && WebView::SupportsForceSharedMemory())
|
||||
::setenv("WEBKIT_DMABUF_RENDERER_FORCE_SHM", "1", /* replace */ false);
|
||||
|
||||
if (x11_opt_in) {
|
||||
// ===== X11 / XWayland (opted in via GDK_BACKEND=x11) =====
|
||||
BOOST_LOG_TRIVIAL(info) << "GDK_BACKEND=x11 detected; applying v2.3.2 X11/XWayland workarounds.";
|
||||
|
||||
@@ -75,7 +75,7 @@ std::vector<float> Layers::get_zs() const
|
||||
|
||||
size_t Layers::get_layer_id_at(float z) const
|
||||
{
|
||||
auto iter = std::upper_bound(m_items.begin(), m_items.end(), z, [](float z, const Item& item) { return item.z < z; });
|
||||
auto iter = std::upper_bound(m_items.begin(), m_items.end(), z, [](float z, const Item& item) { return item.z > z; });
|
||||
return std::distance(m_items.begin(), iter);
|
||||
}
|
||||
|
||||
|
||||
@@ -21178,7 +21178,12 @@ void Plater::print_job_finished(wxCommandEvent &evt)
|
||||
Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
if (!dev) return;
|
||||
|
||||
dev->set_selected_machine(evt.GetString().ToStdString());
|
||||
const std::string dev_id = evt.GetString().ToStdString();
|
||||
MachineObject* selected = dev->get_selected_machine();
|
||||
// After a LAN print, the completion event reselects the same printer.
|
||||
// Keep the active session while asynchronous status traffic may still be in flight.
|
||||
if (!selected || selected->get_dev_id() != dev_id || selected->connection_type() != "lan")
|
||||
dev->set_selected_machine(dev_id);
|
||||
p->main_frame->request_select_tab(TAB_ID_MONITOR);
|
||||
// Selects the status page on a built Device tab; one built by the switch starts there.
|
||||
MonitorPanel* curr_monitor = MonitorPanel::if_built();
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/DeviceCore/DevManager.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/nowide/fstream.hpp>
|
||||
@@ -16,6 +18,7 @@
|
||||
#include <cmath>
|
||||
#include <slic3r/GUI/DeviceManager.hpp>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
using json = nlohmann::json;
|
||||
@@ -64,12 +67,16 @@ const BambuFilamentIdMap& bambu_filament_id_map()
|
||||
return map;
|
||||
}
|
||||
|
||||
// Rewrites every string under "tray_info_idx", "filament_id" or "filamentId", at any depth, in place.
|
||||
// Keys whose string value is a filament id. "cate" and "fila_id" are the H2C nozzle rack's: the
|
||||
// auto nozzle mapping request and the rack status in the push message.
|
||||
constexpr std::array<std::string_view, 5> filament_id_keys{"tray_info_idx", "filament_id", "filamentId", "cate", "fila_id"};
|
||||
|
||||
// Rewrites every string under a filament id key, at any depth, in place.
|
||||
void rewrite_filament_ids(json& j, const std::unordered_map<std::string, std::string>& map)
|
||||
{
|
||||
if (j.is_object()) {
|
||||
for (auto& [key, value] : j.items()) {
|
||||
if (value.is_string() && (key == "tray_info_idx" || key == "filament_id" || key == "filamentId")) {
|
||||
if (value.is_string() && std::find(filament_id_keys.begin(), filament_id_keys.end(), key) != filament_id_keys.end()) {
|
||||
auto it = map.find(value.get_ref<const std::string&>());
|
||||
if (it != map.end())
|
||||
value = it->second;
|
||||
@@ -84,8 +91,8 @@ void rewrite_filament_ids(json& j, const std::unordered_map<std::string, std::st
|
||||
// Text that does not parse as JSON, or that mentions none of the id keys, comes back byte-identical.
|
||||
std::string rewrite_filament_ids(std::string text, const std::unordered_map<std::string, std::string>& map)
|
||||
{
|
||||
if (map.empty() || (text.find("tray_info_idx") == std::string::npos && text.find("filament_id") == std::string::npos &&
|
||||
text.find("filamentId") == std::string::npos))
|
||||
if (map.empty() || std::none_of(filament_id_keys.begin(), filament_id_keys.end(),
|
||||
[&text](std::string_view key) { return text.find(key) != std::string::npos; }))
|
||||
return text; // nothing to map, skip the parse (moved, not copied)
|
||||
try {
|
||||
json j = json::parse(text);
|
||||
|
||||
@@ -81,3 +81,24 @@ TEST_CASE("Payload rewrite covers nested trays, calibration lists and mapping in
|
||||
CHECK(BBLPrinterAgent::from_orca_payload("not json") == "not json");
|
||||
CHECK(BBLPrinterAgent::from_orca_payload(R"({"print":{"command":"pushall"}})") == R"({"print":{"command":"pushall"}})");
|
||||
}
|
||||
|
||||
TEST_CASE("Payload rewrite covers the nozzle rack status and the auto nozzle mapping request", "[BambuFilamentIds]")
|
||||
{
|
||||
const ScopedRepoResourcesDir repo_resources;
|
||||
const std::string petg_hf = orca_id_of("GFG96");
|
||||
|
||||
const std::string rack_status =
|
||||
R"({"print":{"device":{"nozzle":{"info":[{"id":16,"fila_id":"GFG96","color_m":"FFFFFFFF"},{"id":17,"fila_id":"P22f54c9"}]}}}})";
|
||||
json inbound = json::parse(BBLPrinterAgent::to_orca_payload(rack_status));
|
||||
CHECK(inbound["print"]["device"]["nozzle"]["info"][0]["fila_id"] == petg_hf);
|
||||
CHECK(inbound["print"]["device"]["nozzle"]["info"][1]["fila_id"] == "P22f54c9"); // user id: untouched
|
||||
|
||||
const std::string request = R"({"print":{"command":"get_auto_nozzle_mapping","ams_mapping":[65535,65024],)"
|
||||
R"("fila_info":[{"id":2,"cate":")" + petg_hf + R"(","color":"FFFFFFFF"}],)"
|
||||
R"("nozzle_info":[{"pos":16,"cate":")" + petg_hf + R"(","color":"FFFFFFFF"},{"pos":1,"cate":""}]}})";
|
||||
json outbound = json::parse(BBLPrinterAgent::from_orca_payload(request));
|
||||
CHECK(outbound["print"]["fila_info"][0]["cate"] == "GFG96");
|
||||
CHECK(outbound["print"]["nozzle_info"][0]["cate"] == "GFG96");
|
||||
CHECK(outbound["print"]["nozzle_info"][1]["cate"] == ""); // empty nozzle
|
||||
CHECK(outbound["print"]["ams_mapping"] == json::parse("[65535,65024]"));
|
||||
}
|
||||
Reference in new issue
Block a user