Move all GLFW code to a separate class.

This commit is contained in:
Bartosz Taudul 2022-07-27 00:57:42 +02:00
parent 138f80001e
commit b86f1a907a
No known key found for this signature in database
GPG Key ID: B7FE2008B7575DF3
9 changed files with 310 additions and 197 deletions

View File

@ -195,14 +195,15 @@
<ClCompile Include="..\..\..\zstd\dictBuilder\divsufsort.c" />
<ClCompile Include="..\..\..\zstd\dictBuilder\fastcover.c" />
<ClCompile Include="..\..\..\zstd\dictBuilder\zdict.c" />
<ClCompile Include="..\..\src\BackendGlfw.cpp" />
<ClCompile Include="..\..\src\ConnectionHistory.cpp" />
<ClCompile Include="..\..\src\Filters.cpp" />
<ClCompile Include="..\..\src\Fonts.cpp" />
<ClCompile Include="..\..\src\HttpRequest.cpp" />
<ClCompile Include="..\..\src\ImGuiContext.cpp" />
<ClCompile Include="..\..\src\imgui\imgui_impl_glfw.cpp" />
<ClCompile Include="..\..\src\imgui\imgui_impl_opengl3.cpp" />
<ClCompile Include="..\..\src\main.cpp" />
<ClCompile Include="..\..\src\NativeWindow.cpp" />
<ClCompile Include="..\..\src\ResolvService.cpp" />
<ClCompile Include="..\..\src\RunQueue.cpp" />
<ClCompile Include="..\..\src\WindowPosition.cpp" />
@ -316,6 +317,7 @@
<ClInclude Include="..\..\..\zstd\zdict.h" />
<ClInclude Include="..\..\..\zstd\zstd.h" />
<ClInclude Include="..\..\..\zstd\zstd_errors.h" />
<ClInclude Include="..\..\src\Backend.hpp" />
<ClInclude Include="..\..\src\ConnectionHistory.hpp" />
<ClInclude Include="..\..\src\Filters.hpp" />
<ClInclude Include="..\..\src\Fonts.hpp" />
@ -324,10 +326,10 @@
<ClInclude Include="..\..\src\font\FontAwesomeSolid.hpp" />
<ClInclude Include="..\..\src\HttpRequest.hpp" />
<ClInclude Include="..\..\src\icon.hpp" />
<ClInclude Include="..\..\src\ImGuiContext.hpp" />
<ClInclude Include="..\..\src\imgui\imgui_impl_glfw.h" />
<ClInclude Include="..\..\src\imgui\imgui_impl_opengl3.h" />
<ClInclude Include="..\..\src\imgui\imgui_impl_opengl3_loader.h" />
<ClInclude Include="..\..\src\NativeWindow.hpp" />
<ClInclude Include="..\..\src\ResolvService.hpp" />
<ClInclude Include="..\..\src\RunQueue.hpp" />
<ClInclude Include="..\..\src\stb_image.h" />

View File

@ -51,9 +51,6 @@
<ClCompile Include="..\..\src\main.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\..\src\NativeWindow.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\..\..\server\TracyMemory.cpp">
<Filter>server</Filter>
</ClCompile>
@ -348,6 +345,12 @@
<ClCompile Include="..\..\src\Filters.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\..\src\BackendGlfw.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ImGuiContext.cpp">
<Filter>src</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\server\TracyEvent.hpp">
@ -488,9 +491,6 @@
<ClInclude Include="..\..\..\server\TracyMouse.hpp">
<Filter>server</Filter>
</ClInclude>
<ClInclude Include="..\..\src\NativeWindow.hpp">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\..\src\HttpRequest.hpp">
<Filter>src</Filter>
</ClInclude>
@ -707,6 +707,12 @@
<ClInclude Include="..\..\src\Filters.hpp">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\..\src\Backend.hpp">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ImGuiContext.hpp">
<Filter>src</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Natvis Include="DebugVis.natvis" />

34
profiler/src/Backend.hpp Normal file
View File

@ -0,0 +1,34 @@
#ifndef __BACKEND_HPP__
#define __BACKEND_HPP__
#include <functional>
#include <stdint.h>
#include "WindowPosition.hpp"
class RunQueue;
class Backend
{
public:
Backend( const char* title, std::function<void()> redraw, RunQueue* mainThreadTasks );
~Backend();
void Show();
void Run();
void NewFrame( int& w, int& h );
void EndFrame();
void SetIcon( uint8_t* data, int w, int h );
void SetTitle( const char* title );
float GetDpiScale();
void* GetNativeWindow();
private:
WindowPosition m_winPos;
int m_w, m_h;
};
#endif

View File

@ -0,0 +1,194 @@
#include "imgui/imgui_impl_glfw.h"
#include "imgui/imgui_impl_opengl3.h"
#include "imgui/imgui_impl_opengl3_loader.h"
#include <chrono>
#include <GLFW/glfw3.h>
#include <stdio.h>
#include <stdlib.h>
#include <thread>
#ifdef _WIN32
# define GLFW_EXPOSE_NATIVE_WIN32
# include <GLFW/glfw3native.h>
#elif defined __linux__
# ifdef DISPLAY_SERVER_X11
# define GLFW_EXPOSE_NATIVE_X11
# elif defined DISPLAY_SERVER_WAYLAND
# define GLFW_EXPOSE_NATIVE_WAYLAND
# else
# error "unsupported linux display server"
# endif
# include <GLFW/glfw3native.h>
#endif
#include "Backend.hpp"
#include "RunQueue.hpp"
static GLFWwindow* s_window;
static std::function<void()> s_redraw;
static RunQueue* s_mainThreadTasks;
static void glfw_error_callback( int error, const char* description )
{
fprintf(stderr, "Error %d: %s\n", error, description);
}
Backend::Backend( const char* title, std::function<void()> redraw, RunQueue* mainThreadTasks )
{
glfwSetErrorCallback( glfw_error_callback );
if( !glfwInit() ) exit( 1 );
#ifdef DISPLAY_SERVER_WAYLAND
glfwWindowHint( GLFW_ALPHA_BITS, 0 );
#else
glfwWindowHint(GLFW_VISIBLE, 0 );
#endif
glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 );
glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 2 );
glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
#if __APPLE__
glfwWindowHint( GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE );
#endif
s_window = glfwCreateWindow( m_winPos.w, m_winPos.h, title, NULL, NULL );
if( !s_window ) exit( 1 );
glfwSetWindowPos( s_window, m_winPos.x, m_winPos.y );
#ifdef GLFW_MAXIMIZED
if( m_winPos.maximize ) glfwMaximizeWindow( s_window );
#endif
glfwMakeContextCurrent( s_window );
glfwSwapInterval( 1 ); // Enable vsync
glfwSetWindowRefreshCallback( s_window, []( GLFWwindow* ) { s_redraw(); } );
ImGui_ImplGlfw_InitForOpenGL( s_window, true );
ImGui_ImplOpenGL3_Init( "#version 150" );
s_redraw = redraw;
s_mainThreadTasks = mainThreadTasks;
}
Backend::~Backend()
{
#ifdef GLFW_MAXIMIZED
uint32_t maximized = glfwGetWindowAttrib( s_window, GLFW_MAXIMIZED );
if( maximized ) glfwRestoreWindow( s_window );
#else
uint32_t maximized = 0;
#endif
m_winPos.maximize = maximized;
glfwGetWindowPos( s_window, &m_winPos.x, &m_winPos.y );
glfwGetWindowSize( s_window, &m_winPos.w, &m_winPos.h );
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
glfwDestroyWindow( s_window );
glfwTerminate();
}
void Backend::Show()
{
glfwShowWindow( s_window );
}
void Backend::Run()
{
while( !glfwWindowShouldClose( s_window ) )
{
glfwPollEvents();
if( glfwGetWindowAttrib( s_window, GLFW_ICONIFIED ) )
{
std::this_thread::sleep_for( std::chrono::milliseconds( 50 ) );
continue;
}
s_redraw();
if( !glfwGetWindowAttrib( s_window, GLFW_FOCUSED ) )
{
std::this_thread::sleep_for( std::chrono::milliseconds( 50 ) );
}
s_mainThreadTasks->Run();
}
}
void Backend::NewFrame( int& w, int& h )
{
glfwGetFramebufferSize( s_window, &w, &h );
m_w = w;
m_h = h;
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
}
void Backend::EndFrame()
{
const ImVec4 clear_color = ImColor( 114, 144, 154 );
ImGui::Render();
glViewport( 0, 0, m_w, m_h );
glClearColor( clear_color.x, clear_color.y, clear_color.z, clear_color.w );
glClear( GL_COLOR_BUFFER_BIT );
ImGui_ImplOpenGL3_RenderDrawData( ImGui::GetDrawData() );
// Update and Render additional Platform Windows
// (Platform functions may change the current OpenGL context, so we save/restore it to make it easier to paste this code elsewhere.
// For this specific demo app we could also call glfwMakeContextCurrent(window) directly)
if( ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable )
{
GLFWwindow* backup_current_context = glfwGetCurrentContext();
ImGui::UpdatePlatformWindows();
ImGui::RenderPlatformWindowsDefault();
glfwMakeContextCurrent( backup_current_context );
}
glfwSwapBuffers( s_window );
}
void Backend::SetIcon( uint8_t* data, int w, int h )
{
GLFWimage icon;
icon.width = w;
icon.height = h;
icon.pixels = data;
glfwSetWindowIcon( s_window, 1, &icon );
}
void Backend::SetTitle( const char* title )
{
glfwSetWindowTitle( s_window, title );
}
float Backend::GetDpiScale()
{
#if GLFW_VERSION_MAJOR > 3 || ( GLFW_VERSION_MAJOR == 3 && GLFW_VERSION_MINOR >= 3 )
auto monitor = glfwGetWindowMonitor( s_window );
if( !monitor ) monitor = glfwGetPrimaryMonitor();
if( monitor )
{
float x, y;
glfwGetMonitorContentScale( monitor, &x, &y );
return x;
}
#endif
return 1;
}
void* Backend::GetNativeWindow()
{
#ifdef _WIN32
return (void*)glfwGetWin32Window( s_window );
#elif defined __linux__
# ifdef DISPLAY_SERVER_X11
return (void*)glfwGetX11Window( s_window );
# elif defined DISPLAY_SERVER_WAYLAND
return (void*)glfwGetWaylandWindow( s_window );
# endif
#else
return nullptr;
#endif
}

View File

@ -0,0 +1,18 @@
#include <imgui.h>
#include "../../server/TracyStorage.hpp"
#include "ImGuiContext.hpp"
ImGuiTracyContext::ImGuiTracyContext()
: m_iniFilename( tracy::GetSavePath( "imgui.ini" ) )
{
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.IniFilename = m_iniFilename.c_str();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard | ImGuiConfigFlags_DockingEnable;
}
ImGuiTracyContext::~ImGuiTracyContext()
{
ImGui::DestroyContext();
}

View File

@ -0,0 +1,16 @@
#ifndef __IMGUICONTEXT_HPP__
#define __IMGUICONTEXT_HPP__
#include <string>
class ImGuiTracyContext
{
public:
ImGuiTracyContext();
~ImGuiTracyContext();
private:
std::string m_iniFilename;
};
#endif

View File

@ -1,34 +0,0 @@
#include "NativeWindow.hpp"
#include <GLFW/glfw3.h>
#ifdef _WIN32
# define GLFW_EXPOSE_NATIVE_WIN32
# include <GLFW/glfw3native.h>
#elif defined __linux__
# ifdef DISPLAY_SERVER_X11
# define GLFW_EXPOSE_NATIVE_X11
# elif defined DISPLAY_SERVER_WAYLAND
# define GLFW_EXPOSE_NATIVE_WAYLAND
# else
# error "unsupported linux display server"
# endif
# include <GLFW/glfw3native.h>
#endif
extern GLFWwindow* s_glfwWindow;
void* GetMainWindowNative()
{
#ifdef _WIN32
return (void*)glfwGetWin32Window( s_glfwWindow );
#elif defined __linux__
# ifdef DISPLAY_SERVER_X11
return (void*)glfwGetX11Window( s_glfwWindow );
# elif defined DISPLAY_SERVER_WAYLAND
return (void*)glfwGetWaylandWindow( s_glfwWindow );
# endif
#else
return nullptr;
#endif
}

View File

@ -1,6 +0,0 @@
#ifndef __NATIVEWINDOW_HPP__
#define __NATIVEWINDOW_HPP__
void* GetMainWindowNative();
#endif

View File

@ -4,16 +4,12 @@
#include <chrono>
#include <inttypes.h>
#include <imgui.h>
#include "imgui/imgui_impl_glfw.h"
#include "imgui/imgui_impl_opengl3.h"
#include "imgui/imgui_impl_opengl3_loader.h"
#include <mutex>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <unordered_map>
#include <GLFW/glfw3.h>
#include <memory>
#include <sys/stat.h>
#include <locale.h>
@ -54,38 +50,16 @@
#include "icon.hpp"
#include "Backend.hpp"
#include "ConnectionHistory.hpp"
#include "Filters.hpp"
#include "Fonts.hpp"
#include "HttpRequest.hpp"
#include "NativeWindow.hpp"
#include "ImGuiContext.hpp"
#include "ResolvService.hpp"
#include "RunQueue.hpp"
#include "WindowPosition.hpp"
static void glfw_error_callback(int error, const char* description)
{
fprintf(stderr, "Error %d: %s\n", error, description);
}
GLFWwindow* s_glfwWindow = nullptr;
static bool s_customTitle = false;
static void SetWindowTitleCallback( const char* title )
{
assert( s_glfwWindow );
char tmp[1024];
sprintf( tmp, "%s - Tracy Profiler %i.%i.%i", title, tracy::Version::Major, tracy::Version::Minor, tracy::Version::Patch );
glfwSetWindowTitle( s_glfwWindow, tmp );
s_customTitle = true;
}
static void DrawContents();
static void WindowRefreshCallback( GLFWwindow* window )
{
DrawContents();
}
struct ClientData
{
int64_t time;
@ -123,6 +97,23 @@ static uint8_t* iconPx;
static int iconX, iconY;
static void* iconTex;
static int iconTexSz;
static Backend* bptr;
static bool s_customTitle = false;
static void SetWindowTitleCallback( const char* title )
{
char tmp[1024];
sprintf( tmp, "%s - Tracy Profiler %i.%i.%i", title, tracy::Version::Major, tracy::Version::Minor, tracy::Version::Patch );
bptr->SetTitle( tmp );
s_customTitle = true;
}
static void* GetMainWindowNative()
{
return bptr->GetNativeWindow();
}
static void DrawContents();
void RunOnMainThread( std::function<void()> cb, bool forceDelay = false )
{
@ -204,7 +195,6 @@ int main( int argc, char** argv )
}
}
WindowPosition winPos;
ConnectionHistory connHistory;
Filters filters;
@ -223,61 +213,24 @@ int main( int argc, char** argv )
} );
} );
// Setup window
glfwSetErrorCallback(glfw_error_callback);
if( !glfwInit() ) return 1;
#ifdef DISPLAY_SERVER_WAYLAND
glfwWindowHint(GLFW_ALPHA_BITS, 0);
#else
glfwWindowHint(GLFW_VISIBLE, 0);
#endif
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#if __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
GLFWwindow* window = glfwCreateWindow( winPos.w, winPos.h, title, NULL, NULL);
if( !window ) return 1;
iconPx = stbi_load_from_memory( (const stbi_uc*)Icon_data, Icon_size, &iconX, &iconY, nullptr, 4 );
{
GLFWimage icon;
icon.width = iconX;
icon.height = iconY;
icon.pixels = iconPx;
glfwSetWindowIcon( window, 1, &icon );
}
glfwSetWindowPos( window, winPos.x, winPos.y );
#ifdef GLFW_MAXIMIZED
if( winPos.maximize ) glfwMaximizeWindow( window );
#endif
s_glfwWindow = window;
glfwMakeContextCurrent(window);
glfwSwapInterval(1); // Enable vsync
glfwSetWindowRefreshCallback( window, WindowRefreshCallback );
ImGuiTracyContext imguiContext;
Backend backend( title, DrawContents, &mainThreadTasks );
backend.SetIcon( iconPx, iconX, iconY );
bptr = &backend;
#if 0
#ifdef _WIN32
typedef UINT(*GDFS)(void);
GDFS getDpiForSystem = nullptr;
HMODULE dll = GetModuleHandleW(L"user32.dll");
if( dll != INVALID_HANDLE_VALUE ) getDpiForSystem = (GDFS)GetProcAddress(dll, "GetDpiForSystem");
if( getDpiForSystem ) dpiScale = getDpiForSystem() / 96.f;
#elif defined __linux__
# if GLFW_VERSION_MAJOR > 3 || ( GLFW_VERSION_MAJOR == 3 && GLFW_VERSION_MINOR >= 3 )
auto monitor = glfwGetWindowMonitor( window );
if( !monitor ) monitor = glfwGetPrimaryMonitor();
if( monitor )
{
float x, y;
glfwGetMonitorContentScale( monitor, &x, &y );
dpiScale = x;
}
# endif
#endif
#endif
dpiScale = backend.GetDpiScale();
const auto envDpiScale = getenv( "TRACY_DPI_SCALE" );
if( envDpiScale )
{
@ -285,17 +238,6 @@ int main( int argc, char** argv )
if( cnv != 0 ) dpiScale = cnv;
}
// Setup ImGui binding
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
std::string iniFileName = tracy::GetSavePath( "imgui.ini" );
io.IniFilename = iniFileName.c_str();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard | ImGuiConfigFlags_DockingEnable;
ImGui_ImplGlfw_InitForOpenGL( window, true );
ImGui_ImplOpenGL3_Init( "#version 150" );
iconTex = tracy::MakeTexture();
SetupDPIScale( dpiScale, s_fixedWidth, s_bigFont, s_smallFont );
@ -313,57 +255,21 @@ int main( int argc, char** argv )
NFD_Init();
#endif
glfwShowWindow( window );
// Main loop
while (!glfwWindowShouldClose(window))
{
glfwPollEvents();
if( glfwGetWindowAttrib( window, GLFW_ICONIFIED ) )
{
std::this_thread::sleep_for( std::chrono::milliseconds( 50 ) );
continue;
}
DrawContents();
if( !glfwGetWindowAttrib( window, GLFW_FOCUSED ) )
{
std::this_thread::sleep_for( std::chrono::milliseconds( 50 ) );
}
mainThreadTasks.Run();
}
backend.Show();
backend.Run();
if( loadThread.joinable() ) loadThread.join();
if( updateThread.joinable() ) updateThread.join();
if( updateNotesThread.joinable() ) updateNotesThread.join();
view.reset();
#ifdef GLFW_MAXIMIZED
uint32_t maximized = glfwGetWindowAttrib( window, GLFW_MAXIMIZED );
if( maximized ) glfwRestoreWindow( window );
#else
uint32_t maximized = 0;
#endif
winPos.maximize = maximized;
glfwGetWindowPos( window, &winPos.x, &winPos.y );
glfwGetWindowSize( window, &winPos.w, &winPos.h );
tracy::FreeTexture( iconTex, RunOnMainThread );
// Cleanup
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
glfwDestroyWindow(window);
free( iconPx );
#ifndef TRACY_NO_FILESELECTOR
NFD_Quit();
#endif
glfwTerminate();
free( iconPx );
return 0;
}
@ -374,13 +280,8 @@ static void DrawContents()
static uint16_t reconnectPort;
static bool showFilter = false;
const ImVec4 clear_color = ImColor( 114, 144, 154 );
int display_w, display_h;
glfwGetFramebufferSize(s_glfwWindow, &display_w, &display_h);
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
bptr->NewFrame( display_w, display_h );
ImGui::NewFrame();
tracy::MouseFrame();
@ -391,7 +292,7 @@ static void DrawContents()
if( s_customTitle )
{
s_customTitle = false;
glfwSetWindowTitle( s_glfwWindow, title );
bptr->SetTitle( title );
}
const auto time = std::chrono::duration_cast<std::chrono::milliseconds>( std::chrono::system_clock::now().time_since_epoch() ).count();
@ -964,23 +865,5 @@ static void DrawContents()
ImGui::EndPopup();
}
// Rendering
ImGui::Render();
glViewport(0, 0, display_w, display_h);
glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
glClear(GL_COLOR_BUFFER_BIT);
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
// Update and Render additional Platform Windows
// (Platform functions may change the current OpenGL context, so we save/restore it to make it easier to paste this code elsewhere.
// For this specific demo app we could also call glfwMakeContextCurrent(window) directly)
if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
GLFWwindow* backup_current_context = glfwGetCurrentContext();
ImGui::UpdatePlatformWindows();
ImGui::RenderPlatformWindowsDefault();
glfwMakeContextCurrent(backup_current_context);
}
glfwSwapBuffers(s_glfwWindow);
bptr->EndFrame();
}