1
0
mirror of https://github.com/wolfpld/tracy.git synced 2025-03-20 07:40:02 +08:00
tracy/profiler/src/BackendGlfw.cpp
Bartosz Taudul 7dbfed9aea
Drop access to native window.
The new NFD library is not using this information, and the old one was using
it only on Windows. Oh well.

Removal of this functionality also removes some build-time decisions.
2022-08-12 21:44:24 +02:00

184 lines
4.8 KiB
C++

#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>
#include "Backend.hpp"
#include "RunQueue.hpp"
static GLFWwindow* s_window;
static std::function<void()> s_redraw;
static RunQueue* s_mainThreadTasks;
static WindowPosition* s_winPos;
static void glfw_error_callback( int error, const char* description )
{
fprintf(stderr, "Error %d: %s\n", error, description);
}
static void glfw_window_pos_callback( GLFWwindow* window, int x, int y )
{
if( !glfwGetWindowAttrib( window, GLFW_MAXIMIZED) )
{
s_winPos->x = x;
s_winPos->y = y;
}
}
static void glfw_window_size_callback( GLFWwindow* window, int w, int h )
{
if( !glfwGetWindowAttrib( window, GLFW_MAXIMIZED) )
{
s_winPos->w = w;
s_winPos->h = h;
}
}
static void glfw_window_maximize_callback( GLFWwindow*, int maximized )
{
s_winPos->maximize = maximized;
}
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;
s_winPos = &m_winPos;
glfwSetWindowPosCallback( s_window, glfw_window_pos_callback );
glfwSetWindowSizeCallback( s_window, glfw_window_size_callback );
glfwSetWindowMaximizeCallback( s_window, glfw_window_maximize_callback );
}
Backend::~Backend()
{
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;
}