From ea6bc7c5fa1528a32e28127865a13307f40a4cb0 Mon Sep 17 00:00:00 2001 From: Cheng Cao Date: Sun, 22 Jan 2023 05:09:17 -0800 Subject: [PATCH 1/7] fix the GLFW global context issue --- taichi/rhi/opengl/opengl_api.cpp | 16 ++--- taichi/rhi/window_system.cpp | 61 +++++++++++++++++++ taichi/rhi/window_system.h | 12 ++++ .../program_impls/vulkan/vulkan_program.cpp | 12 +--- taichi/ui/backends/vulkan/window.cpp | 3 +- taichi/ui/utils/utils.h | 24 ++------ 6 files changed, 87 insertions(+), 41 deletions(-) create mode 100644 taichi/rhi/window_system.cpp create mode 100644 taichi/rhi/window_system.h diff --git a/taichi/rhi/opengl/opengl_api.cpp b/taichi/rhi/opengl/opengl_api.cpp index 580cbce3cd7ad..19e664c7a0b77 100644 --- a/taichi/rhi/opengl/opengl_api.cpp +++ b/taichi/rhi/opengl/opengl_api.cpp @@ -4,11 +4,10 @@ #include "glad/gl.h" #include "glad/egl.h" -#ifndef ANDROID -#include "GLFW/glfw3.h" -#endif // ANDROID #include "taichi/rhi/opengl/opengl_device.h" +#include "taichi/rhi/window_system.h" + namespace taichi::lang { namespace opengl { @@ -28,12 +27,6 @@ static bool kUseGles = false; static std::optional supported; // std::nullopt void *kGetOpenglProcAddr; -#ifndef ANDROID -static void glfw_error_callback(int code, const char *description) { - TI_WARN("GLFW Error {}: {}", code, description); -} -#endif // ANDROID - bool initialize_opengl(bool use_gles, bool error_tolerance) { TI_TRACE("initialize_opengl({}, {}) called", use_gles, error_tolerance); @@ -52,8 +45,7 @@ bool initialize_opengl(bool use_gles, bool error_tolerance) { void *get_proc_addr = nullptr; #ifndef ANDROID - if (glfwInit()) { - glfwSetErrorCallback(glfw_error_callback); + if (window_system::glfwContextAcquire()) { // Compute Shader requires OpenGL 4.3+ (or OpenGL ES 3.1+) if (use_gles) { glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API); @@ -220,7 +212,7 @@ void reset_opengl() { supported = std::nullopt; kUseGles = false; #ifndef ANDROID - glfwTerminate(); + window_system::glfwContextRelease(); #endif } diff --git a/taichi/rhi/window_system.cpp b/taichi/rhi/window_system.cpp new file mode 100644 index 0000000000000..12f2db2e109b6 --- /dev/null +++ b/taichi/rhi/window_system.cpp @@ -0,0 +1,61 @@ +#include "window_system.h" +#include "taichi/rhi/impl_support.h" + +#include +#include +#include + +namespace taichi::lang::window_system { + +#ifndef ANDROID +struct GLFWState { + std::mutex mutex; + int glfw_ref_count = 0; +}; + +static GLFWState glfw_state; + +static void glfw_error_callback(int code, const char *description) { + std::array buf; + snprintf(buf.data(), buf.size(), "GLFW Error %d: %s", code, description); + RHI_LOG_ERROR(buf.data()); +} + +bool glfwContextAcquire() { + std::lock_guard lg(glfw_state.mutex); + if (glfw_state.glfw_ref_count == 0) { + auto res = glfwInit(); + if (res != GLFW_TRUE) { + return false; + } + + glfwSetErrorCallback(glfw_error_callback); + } + glfw_state.glfw_ref_count++; + return true; +} + +void glfwContextRelease() { + std::lock_guard lg(glfw_state.mutex); + glfw_state.glfw_ref_count--; + if (glfw_state.glfw_ref_count == 0) { + glfwTerminate(); + } else if (glfw_state.glfw_ref_count < 0) { + assert(false && "GLFW context double release?"); + } +} + +#else + +bool glfwContextAcquire() { + return false; +} + +void glfwContextRelease() { + return; +} + +#endif // ANDROID + + +} diff --git a/taichi/rhi/window_system.h b/taichi/rhi/window_system.h new file mode 100644 index 0000000000000..6fed1defc0581 --- /dev/null +++ b/taichi/rhi/window_system.h @@ -0,0 +1,12 @@ +#pragma once + +#ifndef ANDROID +#include "GLFW/glfw3.h" +#endif // ANDROID + +namespace taichi::lang::window_system { + +bool glfwContextAcquire(); +void glfwContextRelease(); + +} diff --git a/taichi/runtime/program_impls/vulkan/vulkan_program.cpp b/taichi/runtime/program_impls/vulkan/vulkan_program.cpp index 6d0b5f5759335..424b89a8a2ce9 100644 --- a/taichi/runtime/program_impls/vulkan/vulkan_program.cpp +++ b/taichi/runtime/program_impls/vulkan/vulkan_program.cpp @@ -7,9 +7,7 @@ #include "taichi/runtime/gfx/aot_module_loader_impl.h" #include "taichi/util/offline_cache.h" -#if !defined(ANDROID) -#include "GLFW/glfw3.h" -#endif +#include "taichi/rhi/window_system.h" using namespace taichi::lang::vulkan; @@ -85,10 +83,6 @@ FunctionType VulkanProgramImpl::compile(const CompileConfig &compile_config, vulkan_runtime_.get()); } -static void glfw_error_callback(int code, const char *description) { - TI_WARN("GLFW Error {}: {}", code, description); -} - void VulkanProgramImpl::materialize_runtime(MemoryPool *memory_pool, KernelProfilerBase *profiler, uint64 **result_buffer_ptr) { @@ -101,9 +95,7 @@ void VulkanProgramImpl::materialize_runtime(MemoryPool *memory_pool, #ifndef ANDROID GLFWwindow *glfw_window = nullptr; - if (glfwInit()) { - glfwSetErrorCallback(glfw_error_callback); - + if (window_system::glfwContextAcquire()) { // glfw init success glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); diff --git a/taichi/ui/backends/vulkan/window.cpp b/taichi/ui/backends/vulkan/window.cpp index e34fdafc7f74b..6d7adae7edf75 100644 --- a/taichi/ui/backends/vulkan/window.cpp +++ b/taichi/ui/backends/vulkan/window.cpp @@ -3,6 +3,7 @@ #include "taichi/program/program.h" #include "taichi/ui/utils/utils.h" +#include "taichi/rhi/window_system.h" using taichi::lang::Program; @@ -91,7 +92,7 @@ Window::~Window() { gui_.reset(); renderer_.reset(); if (config_.show_window) { - glfwTerminate(); + taichi::lang::window_system::glfwContextRelease(); } } diff --git a/taichi/ui/utils/utils.h b/taichi/ui/utils/utils.h index 1e9ad0fae99eb..b2a28f050bda0 100644 --- a/taichi/ui/utils/utils.h +++ b/taichi/ui/utils/utils.h @@ -33,9 +33,7 @@ #endif #include "taichi/rhi/vulkan/vulkan_common.h" -#if !defined(ANDROID) -#include -#endif +#include "taichi/rhi/window_system.h" #include @@ -47,28 +45,18 @@ namespace taichi::ui { #if !defined(ANDROID) -inline void initGLFW() { - if (!glfwInit()) { - printf("cannot initialize GLFW\n"); - exit(EXIT_FAILURE); - } -} - -static void glfw_error_callback(int code, const char *description) { - printf("GLFW Error %d: %s\n", code, description); -} - inline GLFWwindow *create_glfw_window_(const std::string &name, int screenWidth, int screenHeight, int window_pos_x, int window_pos_y, bool vsync) { - initGLFW(); + if (!taichi::lang::window_system::glfwContextAcquire()) { + printf("cannot initialize GLFW\n"); + exit(EXIT_FAILURE); + } GLFWwindow *window; - glfwSetErrorCallback(glfw_error_callback); - glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); @@ -76,7 +64,7 @@ inline GLFWwindow *create_glfw_window_(const std::string &name, nullptr); if (!window) { - glfwTerminate(); + taichi::lang::window_system::glfwContextRelease(); exit(EXIT_FAILURE); } From aa2a9a0f0c3726780aaf5c5ad55fc04fe629ae2f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 22 Jan 2023 21:01:35 +0000 Subject: [PATCH 2/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- taichi/rhi/window_system.cpp | 5 ++--- taichi/rhi/window_system.h | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/taichi/rhi/window_system.cpp b/taichi/rhi/window_system.cpp index 12f2db2e109b6..33377637b31f2 100644 --- a/taichi/rhi/window_system.cpp +++ b/taichi/rhi/window_system.cpp @@ -28,7 +28,7 @@ bool glfwContextAcquire() { if (res != GLFW_TRUE) { return false; } - + glfwSetErrorCallback(glfw_error_callback); } glfw_state.glfw_ref_count++; @@ -57,5 +57,4 @@ void glfwContextRelease() { #endif // ANDROID - -} +} // namespace taichi::lang::window_system diff --git a/taichi/rhi/window_system.h b/taichi/rhi/window_system.h index 6fed1defc0581..a72b6a657483c 100644 --- a/taichi/rhi/window_system.h +++ b/taichi/rhi/window_system.h @@ -9,4 +9,4 @@ namespace taichi::lang::window_system { bool glfwContextAcquire(); void glfwContextRelease(); -} +} // namespace taichi::lang::window_system From 7213a495dc7076b22b490d567988f19061643d87 Mon Sep 17 00:00:00 2001 From: Cheng Cao Date: Sun, 22 Jan 2023 05:11:54 -0800 Subject: [PATCH 3/7] fix naming --- taichi/rhi/opengl/opengl_api.cpp | 4 ++-- taichi/rhi/window_system.cpp | 8 ++++---- taichi/rhi/window_system.h | 4 ++-- taichi/runtime/program_impls/vulkan/vulkan_program.cpp | 2 +- taichi/ui/backends/vulkan/window.cpp | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/taichi/rhi/opengl/opengl_api.cpp b/taichi/rhi/opengl/opengl_api.cpp index 19e664c7a0b77..c5898c3e2b4a9 100644 --- a/taichi/rhi/opengl/opengl_api.cpp +++ b/taichi/rhi/opengl/opengl_api.cpp @@ -45,7 +45,7 @@ bool initialize_opengl(bool use_gles, bool error_tolerance) { void *get_proc_addr = nullptr; #ifndef ANDROID - if (window_system::glfwContextAcquire()) { + if (window_system::glfw_context_acquire()) { // Compute Shader requires OpenGL 4.3+ (or OpenGL ES 3.1+) if (use_gles) { glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API); @@ -212,7 +212,7 @@ void reset_opengl() { supported = std::nullopt; kUseGles = false; #ifndef ANDROID - window_system::glfwContextRelease(); + window_system::glfw_context_release(); #endif } diff --git a/taichi/rhi/window_system.cpp b/taichi/rhi/window_system.cpp index 12f2db2e109b6..636f2478d136c 100644 --- a/taichi/rhi/window_system.cpp +++ b/taichi/rhi/window_system.cpp @@ -21,7 +21,7 @@ static void glfw_error_callback(int code, const char *description) { RHI_LOG_ERROR(buf.data()); } -bool glfwContextAcquire() { +bool glfw_context_acquire() { std::lock_guard lg(glfw_state.mutex); if (glfw_state.glfw_ref_count == 0) { auto res = glfwInit(); @@ -35,7 +35,7 @@ bool glfwContextAcquire() { return true; } -void glfwContextRelease() { +void glfw_context_release() { std::lock_guard lg(glfw_state.mutex); glfw_state.glfw_ref_count--; if (glfw_state.glfw_ref_count == 0) { @@ -47,11 +47,11 @@ void glfwContextRelease() { #else -bool glfwContextAcquire() { +bool glfw_context_acquire() { return false; } -void glfwContextRelease() { +void glfw_context_release() { return; } diff --git a/taichi/rhi/window_system.h b/taichi/rhi/window_system.h index 6fed1defc0581..09cf7b55f4a88 100644 --- a/taichi/rhi/window_system.h +++ b/taichi/rhi/window_system.h @@ -6,7 +6,7 @@ namespace taichi::lang::window_system { -bool glfwContextAcquire(); -void glfwContextRelease(); +bool glfw_context_acquire(); +void glfw_context_release(); } diff --git a/taichi/runtime/program_impls/vulkan/vulkan_program.cpp b/taichi/runtime/program_impls/vulkan/vulkan_program.cpp index 424b89a8a2ce9..1536119643e29 100644 --- a/taichi/runtime/program_impls/vulkan/vulkan_program.cpp +++ b/taichi/runtime/program_impls/vulkan/vulkan_program.cpp @@ -95,7 +95,7 @@ void VulkanProgramImpl::materialize_runtime(MemoryPool *memory_pool, #ifndef ANDROID GLFWwindow *glfw_window = nullptr; - if (window_system::glfwContextAcquire()) { + if (window_system::glfw_context_acquire()) { // glfw init success glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); diff --git a/taichi/ui/backends/vulkan/window.cpp b/taichi/ui/backends/vulkan/window.cpp index 6d7adae7edf75..6545c763c99af 100644 --- a/taichi/ui/backends/vulkan/window.cpp +++ b/taichi/ui/backends/vulkan/window.cpp @@ -92,7 +92,7 @@ Window::~Window() { gui_.reset(); renderer_.reset(); if (config_.show_window) { - taichi::lang::window_system::glfwContextRelease(); + taichi::lang::window_system::glfw_context_release(); } } From e71848d2805d05137645b35561d5ddd5593d76d5 Mon Sep 17 00:00:00 2001 From: Cheng Cao Date: Sun, 22 Jan 2023 05:14:22 -0800 Subject: [PATCH 4/7] fix naming --- taichi/ui/utils/utils.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/taichi/ui/utils/utils.h b/taichi/ui/utils/utils.h index b2a28f050bda0..ba1e6588e7145 100644 --- a/taichi/ui/utils/utils.h +++ b/taichi/ui/utils/utils.h @@ -51,7 +51,7 @@ inline GLFWwindow *create_glfw_window_(const std::string &name, int window_pos_x, int window_pos_y, bool vsync) { - if (!taichi::lang::window_system::glfwContextAcquire()) { + if (!taichi::lang::window_system::glfw_context_acquire()) { printf("cannot initialize GLFW\n"); exit(EXIT_FAILURE); } @@ -64,7 +64,7 @@ inline GLFWwindow *create_glfw_window_(const std::string &name, nullptr); if (!window) { - taichi::lang::window_system::glfwContextRelease(); + taichi::lang::window_system::glfw_context_release(); exit(EXIT_FAILURE); } From 21bc7aca5292472de56b483a4addd92b27c1b946 Mon Sep 17 00:00:00 2001 From: Cheng Cao Date: Sun, 22 Jan 2023 13:13:12 -0800 Subject: [PATCH 5/7] Fix compile --- cmake/TaichiCore.cmake | 1 + taichi/rhi/window_system.cpp | 4 ++-- taichi/rhi/window_system.h | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/cmake/TaichiCore.cmake b/cmake/TaichiCore.cmake index f07ae3254dabe..5a9efd9672e5c 100644 --- a/cmake/TaichiCore.cmake +++ b/cmake/TaichiCore.cmake @@ -159,6 +159,7 @@ if (TI_WITH_OPENGL OR TI_WITH_VULKAN AND NOT ANDROID) endif() message("Building with GLFW") + target_compile_definitions(${CORE_LIBRARY_NAME} PRIVATE TI_WITH_GLFW) add_subdirectory(external/glfw) target_link_libraries(${CORE_LIBRARY_NAME} PRIVATE glfw) target_include_directories(${CORE_LIBRARY_NAME} PUBLIC external/glfw/include) diff --git a/taichi/rhi/window_system.cpp b/taichi/rhi/window_system.cpp index 636f2478d136c..457ec64953d53 100644 --- a/taichi/rhi/window_system.cpp +++ b/taichi/rhi/window_system.cpp @@ -7,7 +7,7 @@ namespace taichi::lang::window_system { -#ifndef ANDROID +#ifdef TI_WITH_GLFW struct GLFWState { std::mutex mutex; int glfw_ref_count = 0; @@ -55,7 +55,7 @@ void glfw_context_release() { return; } -#endif // ANDROID +#endif // TI_WITH_GLFW } diff --git a/taichi/rhi/window_system.h b/taichi/rhi/window_system.h index 09cf7b55f4a88..29a82a2fe4b47 100644 --- a/taichi/rhi/window_system.h +++ b/taichi/rhi/window_system.h @@ -1,8 +1,8 @@ #pragma once -#ifndef ANDROID +#ifdef TI_WITH_GLFW #include "GLFW/glfw3.h" -#endif // ANDROID +#endif // TI_WITH_GLFW namespace taichi::lang::window_system { From ba40041aa9d791933e99fd0f5bdc5bf03db38da9 Mon Sep 17 00:00:00 2001 From: Cheng Cao Date: Sun, 22 Jan 2023 13:20:38 -0800 Subject: [PATCH 6/7] fix compile again --- taichi/ui/utils/utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/taichi/ui/utils/utils.h b/taichi/ui/utils/utils.h index ba1e6588e7145..d8f2dc985af80 100644 --- a/taichi/ui/utils/utils.h +++ b/taichi/ui/utils/utils.h @@ -44,7 +44,7 @@ namespace taichi::ui { -#if !defined(ANDROID) +#ifdef TI_WITH_GLFW inline GLFWwindow *create_glfw_window_(const std::string &name, int screenWidth, int screenHeight, From 5e9d20dc6f85f0c6ed42702eb7bdac053cd4798b Mon Sep 17 00:00:00 2001 From: Cheng Cao Date: Sun, 22 Jan 2023 13:25:39 -0800 Subject: [PATCH 7/7] more fixes --- cmake/TaichiCore.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/TaichiCore.cmake b/cmake/TaichiCore.cmake index 5a9efd9672e5c..b106039ac8a1c 100644 --- a/cmake/TaichiCore.cmake +++ b/cmake/TaichiCore.cmake @@ -159,7 +159,7 @@ if (TI_WITH_OPENGL OR TI_WITH_VULKAN AND NOT ANDROID) endif() message("Building with GLFW") - target_compile_definitions(${CORE_LIBRARY_NAME} PRIVATE TI_WITH_GLFW) + add_compile_definitions(TI_WITH_GLFW) add_subdirectory(external/glfw) target_link_libraries(${CORE_LIBRARY_NAME} PRIVATE glfw) target_include_directories(${CORE_LIBRARY_NAME} PUBLIC external/glfw/include)