From bad51cdb520919362100b4381b9bb03cd1830643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hejl?= Date: Mon, 2 Aug 2021 14:03:17 +0200 Subject: [PATCH] OSX specific: Fixed darker colors of objects inside multi-material gizmo on macOS running on Arm64 CPU. For Apple's on Arm CPU computed triangle normals inside fragment shader using dFdx and dFdy has the opposite direction. Because of this, objects had darker colors inside the multi-material gizmo. Based on https://stackoverflow.com/a/66206648, the similar behavior was also spotted on some other devices with Arm CPU. --- resources/shaders/gouraud.fs | 3 +++ src/libslic3r/Platform.cpp | 41 +++++++++++++++++++++++++++-- src/libslic3r/Platform.hpp | 6 +++++ src/slic3r/GUI/GLShadersManager.cpp | 15 +++++++++-- 4 files changed, 61 insertions(+), 4 deletions(-) diff --git a/resources/shaders/gouraud.fs b/resources/shaders/gouraud.fs index 572b37c7f..2f2ca5fb5 100644 --- a/resources/shaders/gouraud.fs +++ b/resources/shaders/gouraud.fs @@ -64,6 +64,9 @@ void main() float world_normal_z_fs = world_normal_z; if (compute_triangle_normals_in_fs) { vec3 triangle_normal = normalize(cross(dFdx(model_pos.xyz), dFdy(model_pos.xyz))); +#ifdef FLIP_TRIANGLE_NORMALS + triangle_normal = -triangle_normal; +#endif // First transform the normal into camera space and normalize the result. eye_normal_fs = normalize(gl_NormalMatrix * triangle_normal); diff --git a/src/libslic3r/Platform.cpp b/src/libslic3r/Platform.cpp index ae02c42b3..4aa72c95f 100644 --- a/src/libslic3r/Platform.cpp +++ b/src/libslic3r/Platform.cpp @@ -3,6 +3,12 @@ #include #include +#if defined(__APPLE__) +#include +#include +#include +#endif + namespace Slic3r { static auto s_platform = Platform::Uninitialized; @@ -16,8 +22,39 @@ void detect_platform() s_platform_flavor = PlatformFlavor::Generic; #elif defined(__APPLE__) BOOST_LOG_TRIVIAL(info) << "Platform: OSX"; - s_platform = Platform::OSX; - s_platform_flavor = PlatformFlavor::Generic; + s_platform = Platform::OSX; + s_platform_flavor = PlatformFlavor::GenericOSX; + { + cpu_type_t type = 0; + size_t size = sizeof(type); + if (sysctlbyname("hw.cputype", &type, &size, NULL, 0) == 0) { + type &= ~CPU_ARCH_MASK; + if (type == CPU_TYPE_X86) { + int proc_translated = 0; + size = sizeof(proc_translated); + // Detect if native CPU is really X86 or PrusaSlicer runs through Rosetta. + if (sysctlbyname("sysctl.proc_translated", &proc_translated, &size, NULL, 0) == -1) { + if (errno == ENOENT) { + // Native CPU is X86, and property sysctl.proc_translated doesn't exist. + s_platform_flavor = PlatformFlavor::OSXOnX86; + BOOST_LOG_TRIVIAL(info) << "Platform flavor: OSXOnX86"; + } + } else if (proc_translated == 1) { + // Native CPU is ARM and PrusaSlicer runs through Rosetta. + s_platform_flavor = PlatformFlavor::OSXOnArm; + BOOST_LOG_TRIVIAL(info) << "Platform flavor: OSXOnArm"; + } else { + // Native CPU is X86. + s_platform_flavor = PlatformFlavor::OSXOnX86; + BOOST_LOG_TRIVIAL(info) << "Platform flavor: OSXOnX86"; + } + } else if (type == CPU_TYPE_ARM) { + // Native CPU is ARM + s_platform_flavor = PlatformFlavor::OSXOnArm; + BOOST_LOG_TRIVIAL(info) << "Platform flavor: OSXOnArm"; + } + } + } #elif defined(__linux__) BOOST_LOG_TRIVIAL(info) << "Platform: Linux"; s_platform = Platform::Linux; diff --git a/src/libslic3r/Platform.hpp b/src/libslic3r/Platform.hpp index 735728e89..1b4d74c02 100644 --- a/src/libslic3r/Platform.hpp +++ b/src/libslic3r/Platform.hpp @@ -28,6 +28,12 @@ enum class PlatformFlavor WSL2, // For Platform::BSDUnix OpenBSD, + // For Platform::OSX + GenericOSX, + // For Apple's on Intel X86 CPU + OSXOnX86, + // For Apple's on Arm CPU + OSXOnArm, }; // To be called on program start-up. diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index 5ee14c526..788fe90c0 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -1,4 +1,5 @@ #include "libslic3r/libslic3r.h" +#include "libslic3r/Platform.hpp" #include "GLShadersManager.hpp" #include "3DScene.hpp" #include "GUI_App.hpp" @@ -43,9 +44,19 @@ std::pair GLShadersManager::init() // used to render extrusion and travel paths as lines in gcode preview valid &= append_shader("toolpaths_lines", { "toolpaths_lines.vs", "toolpaths_lines.fs" }); // used to render objects in 3d editor - valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" } + // For Apple's on Arm CPU computed triangle normals inside fragment shader using dFdx and dFdy has the opposite direction. + // Because of this, objects had darker colors inside the multi-material gizmo. + // Based on https://stackoverflow.com/a/66206648, the similar behavior was also spotted on some other devices with Arm CPU. + if (platform_flavor() == PlatformFlavor::OSXOnArm) + valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" }, { "FLIP_TRIANGLE_NORMALS"sv #if ENABLE_ENVIRONMENT_MAP - , { "ENABLE_ENVIRONMENT_MAP"sv } + , "ENABLE_ENVIRONMENT_MAP"sv +#endif + }); + else + valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" } +#if ENABLE_ENVIRONMENT_MAP + , { "ENABLE_ENVIRONMENT_MAP"sv } #endif ); // used to render variable layers heights in 3d editor