diff --git a/meson.build b/meson.build index 4957fb49..f4406c11 100644 --- a/meson.build +++ b/meson.build @@ -235,9 +235,9 @@ dearimgui_sp = subproject('imgui', default_options: [ 'dx11=disabled', 'dx12=disabled', 'metal=disabled', - 'opengl=disabled', + 'opengl=enabled', 'vulkan=disabled', - 'glfw=disabled', + 'glfw=enabled', 'sdl2=disabled', 'osx=disabled', 'win=disabled', @@ -267,5 +267,7 @@ else windows_deps = null_dep endif +glfw3_dep = dependency('glfw3') + subdir('src') subdir('data') diff --git a/src/app/main.cpp b/src/app/main.cpp new file mode 100644 index 00000000..90b9967c --- /dev/null +++ b/src/app/main.cpp @@ -0,0 +1,199 @@ +// Dear ImGui: standalone example application for GLFW + OpenGL 3, using programmable pipeline +// (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +#include "imgui.h" +#include "imgui_impl_glfw.h" +#include "imgui_impl_opengl3.h" +#include +#include +#include +#include +#include "../overlay.h" + +// About Desktop OpenGL function loaders: +// Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers. +// Helper libraries are often used for this purpose! Here we are supporting a few common ones (gl3w, glew, glad). +// You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own. +#if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) +#include "GL/gl3w.h" // Initialize with gl3wInit() +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) +#include // Initialize with glewInit() +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) +#include // Initialize with gladLoadGL() +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD2) +#include // Initialize with gladLoadGL(...) or gladLoaderLoadGL() +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) +#define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors. +#include // Initialize with glbinding::Binding::initialize() +#include +using namespace gl; +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) +#define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors. +#include // Initialize with glbinding::initialize() +#include +using namespace gl; +#else +#include IMGUI_IMPL_OPENGL_LOADER_CUSTOM +#endif + +// Include glfw3.h after our OpenGL definitions +#include + +// [Win32] Our example includes a copy of glfw3.lib pre-compiled with VS2010 to maximize ease of testing and compatibility with old VS compilers. +// To link with VS2010-era libraries, VS2015+ requires linking with legacy_stdio_definitions.lib, which we do using this pragma. +// Your own project should not be affected, as you are likely to link with a newer binary of GLFW that is adequate for your version of Visual Studio. +#if defined(_MSC_VER) && (_MSC_VER >= 1900) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) +#pragma comment(lib, "legacy_stdio_definitions") +#endif + +static void glfw_error_callback(int error, const char* description) +{ + fprintf(stderr, "Glfw Error %d: %s\n", error, description); +} +swapchain_stats sw_stats {}; +overlay_params params {}; +static ImVec2 window_size; +static uint32_t vendorID; +static std::string deviceName; +int fd; +char str1[80]; +char *shm_str; + +void read_thread(){ + while (1){ + if (strcmp("read", shm_str)) { + sprintf(shm_str, "%s", "read"); + update_hud_info(sw_stats, params, vendorID); + } else { + sleep(0.0001); + } + } +} + +int main(int, char**) +{ + // Setup window + glfwSetErrorCallback(glfw_error_callback); + if (!glfwInit()) + return 1; + + const char* glsl_version = "#version 130"; + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); + + glfwWindowHint(GLFW_RESIZABLE, 1); + glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, 1); + + // Create window with graphics context + GLFWwindow* window = glfwCreateWindow(1280, 720, "Dear ImGui GLFW+OpenGL3 example", NULL, NULL); + if (window == NULL) + return 1; + glfwMakeContextCurrent(window); + glfwSwapInterval(1); // Enable vsync + + // Initialize OpenGL loader +#if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) + bool err = gl3wInit() != 0; +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) + bool err = glewInit() != GLEW_OK; +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) + bool err = gladLoadGL() == 0; +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD2) + bool err = gladLoadGL(glfwGetProcAddress) == 0; // glad2 recommend using the windowing library loader instead of the (optionally) bundled one. +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) + bool err = false; + glbinding::Binding::initialize(); +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) + bool err = false; + glbinding::initialize([](const char* name) { return (glbinding::ProcAddress)glfwGetProcAddress(name); }); +#else + bool err = false; // If you use IMGUI_IMPL_OPENGL_LOADER_CUSTOM, your loader is likely to requires some form of initialization. +#endif + if (err) + { + fprintf(stderr, "Failed to initialize OpenGL loader!\n"); + return 1; + } + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); + + // Setup Platform/Renderer backends + ImGui_ImplGlfw_InitForOpenGL(window, true); + ImGui_ImplOpenGL3_Init(glsl_version); + parse_overlay_config(¶ms, getenv("MANGOHUD_CONFIG")); + create_fonts(params, sw_stats.font1, sw_stats.font_text); + HUDElements.convert_colors(params); + init_cpu_stats(params); + deviceName = (char*)glGetString(GL_RENDERER); + sw_stats.deviceName = deviceName; + if (deviceName.find("Radeon") != std::string::npos + || deviceName.find("AMD") != std::string::npos){ + vendorID = 0x1002; + } else { + vendorID = 0x10de; + } + init_gpu_stats(vendorID, params); + init_system_info(); + + // Our state + key_t key = ftok("mangoapp",65); + int shmid = shmget(key,1024,0666|IPC_CREAT); + shm_str = (char*) shmat(shmid,(void*)0,0); + std::thread(read_thread).detach(); + // Main loop + while (!glfwWindowShouldClose(window)) + { + // Poll and handle events (inputs, window resize, etc.) + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. + glfwPollEvents(); + + // Start the Dear ImGui frame + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + + ImGui::NewFrame(); + { + check_keybinds(sw_stats, params, vendorID); + position_layer(sw_stats, params, window_size); + render_imgui(sw_stats, params, window_size, true); + } + ImGui::PopStyleVar(3); + + // Rendering + ImGui::Render(); + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + glEnable(GL_DEPTH_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + + glfwSwapBuffers(window); + } + + // Cleanup + ImGui_ImplOpenGL3_Shutdown(); + ImGui_ImplGlfw_Shutdown(); + ImGui::DestroyContext(); + + glfwDestroyWindow(window); + glfwTerminate(); + + return 0; +} diff --git a/src/meson.build b/src/meson.build index 46b717d0..8c1f6453 100644 --- a/src/meson.build +++ b/src/meson.build @@ -161,7 +161,7 @@ if is_unixy endif endif -link_args = cc.get_supported_link_arguments(['-Wl,-Bsymbolic-functions', '-Wl,-z,relro', '-Wl,--exclude-libs,ALL']) +link_args = cc.get_supported_link_arguments(['-Wl,-Bsymbolic-functions', '-Wl,-z,relro', '-Wl,--exclude-libs,ALL', '-lglfw', '-lGL']) # meson fails to check version-script so just force add link_args += '-Wl,--version-script,@0@'.format(join_paths(meson.current_source_dir(), 'mangohud.version')) @@ -224,6 +224,70 @@ if is_unixy ) endif +if sizeof_ptr == 8 + pre_args += '-DIMGUI_IMPL_OPENGL_LOADER_GLEW' + overlay_files = files( + 'overlay.cpp', + 'hud_elements.cpp', + 'gpu.cpp', + 'nvml.cpp', + 'loaders/loader_nvml.cpp', + 'loaders/loader_nvctrl.cpp', + 'nvctrl.cpp', + 'logging.cpp', + 'battery.cpp', + 'memory.cpp', + 'cpu.cpp', + 'pci_ids.cpp', + 'file_utils.cpp', + 'iostats.cpp', + 'dbus.cpp', + 'loaders/loader_libdrm.cpp', + 'overlay_params.cpp', + 'loaders/loader_x11.cpp', + 'loaders/loader_dbus.cpp', + 'config.cpp', + 'blacklist.cpp', + 'font.cpp', + 'keybinds.cpp', + 'font_unispace.c', + 'loaders/loader_x11.cpp', + 'shared_x11.cpp', + ) + mangoapp = executable( + 'mangoapp', + mangohud_version, + util_files, + vk_enum_to_str, + overlay_files, + files( + 'app/main.cpp', + ), + c_args : [ + pre_args, + no_override_init_args, + vulkan_wsi_args + ], + cpp_args : [ + pre_args, + vulkan_wsi_args + ], + gnu_symbol_visibility : 'hidden', + dependencies : [ + dearimgui_dep, + dep_dl, + spdlog_dep, + dbus_dep, + dep_libdrm, + dep_x11, + glfw3_dep, + ], + include_directories : [inc_common], + link_args : link_args, + install : true + ) +endif + configure_file(input : 'mangohud.json.in', output : '@0@.json'.format(meson.project_name()), configuration : {'ld_libdir_mangohud' : ld_libdir_mangohud_vk, diff --git a/src/overlay.cpp b/src/overlay.cpp index 6f37a993..69e3d40c 100644 --- a/src/overlay.cpp +++ b/src/overlay.cpp @@ -169,6 +169,7 @@ void update_hud_info(struct swapchain_stats& sw_stats, struct overlay_params& pa } frametime = (now - sw_stats.last_present_time) / 1000; + if (elapsed >= params.fps_sampling_period) { if (!hw_update_thread) hw_update_thread = std::make_unique(); diff --git a/src/overlay.h b/src/overlay.h index e4e7141f..6fe43b46 100644 --- a/src/overlay.h +++ b/src/overlay.h @@ -129,4 +129,4 @@ void stop_hw_updater(); void render_mpris_metadata(overlay_params& params, mutexed_metadata& meta, uint64_t frame_timing); #endif -#endif //MANGOHUD_OVERLAY_H +#endif //MANGOHUD_OVERLAY_H \ No newline at end of file