Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move Window and Gui calls to port game loop #787

Merged
merged 6 commits into from
Jan 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions src/graphic/Fast3D/Fast3dWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,38 @@ void Fast3dWindow::StartFrame() {
}

void Fast3dWindow::EndFrame() {
gfx_end_frame();
}

bool Fast3dWindow::IsFrameReady() {
return mWindowManagerApi->is_frame_ready();
}

bool Fast3dWindow::DrawAndRunGraphicsCommands(Gfx* commands, const std::unordered_map<Mtx*, MtxF>& mtxReplacements) {
std::shared_ptr<Window> wnd = Ship::Context::GetInstance()->GetWindow();

// Skip dropped frames
if (!wnd->IsFrameReady()) {
return false;
}

auto gui = wnd->GetGui();
// Setup of the backend frames and draw initial Window and GUI menus
gui->StartDraw();
// Setup game framebuffers to match available window space
gfx_start_frame();
// Execute the games gfx commands
gfx_run(commands, mtxReplacements);
// Renders the game frame buffer to the final window and finishes the GUI
gui->EndDraw();
// Finalize swap buffers
gfx_end_frame();

return true;
}

void Fast3dWindow::HandleEvents() {
mWindowManagerApi->handle_events();
}

void Fast3dWindow::SetCursorVisibility(bool visible) {
Expand Down
5 changes: 5 additions & 0 deletions src/graphic/Fast3D/Fast3dWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include "public/bridge/gfxbridge.h"
#include "controller/controldevice/controller/mapping/keyboard/KeyboardScancodes.h"

union Gfx;

namespace Fast {
class Fast3dWindow : public Ship::Window {
public:
Expand All @@ -16,6 +18,8 @@ class Fast3dWindow : public Ship::Window {
void Close() override;
void StartFrame() override;
void EndFrame() override;
bool IsFrameReady() override;
void HandleEvents() override;
void SetCursorVisibility(bool visible) override;
uint32_t GetWidth() override;
uint32_t GetHeight() override;
Expand Down Expand Up @@ -46,6 +50,7 @@ class Fast3dWindow : public Ship::Window {
void SetTextureFilter(FilteringMode filteringMode);
void SetRendererUCode(UcodeHandlers ucode);
void EnableSRGBMode();
bool DrawAndRunGraphicsCommands(Gfx* commands, const std::unordered_map<Mtx*, MtxF>& mtxReplacements);

protected:
static bool KeyDown(int32_t scancode);
Expand Down
4 changes: 2 additions & 2 deletions src/graphic/Fast3D/gfx_dxgi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,7 @@ static uint64_t qpc_to_100ns(uint64_t qpc) {
qpc % dxgi.qpc_freq * _100NANOSECONDS_IN_SECOND / dxgi.qpc_freq;
}

static bool gfx_dxgi_start_frame() {
static bool gfx_dxgi_is_frame_ready() {
DXGI_FRAME_STATISTICS stats;
if (dxgi.swap_chain->GetFrameStatistics(&stats) == S_OK &&
(stats.SyncRefreshCount != 0 || stats.SyncQPCTime.QuadPart != 0ULL)) {
Expand Down Expand Up @@ -1058,7 +1058,7 @@ extern "C" struct GfxWindowManagerAPI gfx_dxgi_api = { gfx_dxgi_init,
gfx_dxgi_is_mouse_captured,
gfx_dxgi_get_dimensions,
gfx_dxgi_handle_events,
gfx_dxgi_start_frame,
gfx_dxgi_is_frame_ready,
gfx_dxgi_swap_buffers_begin,
gfx_dxgi_swap_buffers_end,
gfx_dxgi_get_time,
Expand Down
4 changes: 1 addition & 3 deletions src/graphic/Fast3D/gfx_metal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,13 +234,11 @@ bool Metal_Init(SDL_Renderer* renderer) {

static void gfx_metal_setup_screen_framebuffer(uint32_t width, uint32_t height);

void Metal_SetupFrame(SDL_Renderer* renderer) {
void Metal_NewFrame(SDL_Renderer* renderer) {
int width, height;
SDL_GetRendererOutputSize(renderer, &width, &height);
gfx_metal_setup_screen_framebuffer(width, height);
}

void Metal_NewFrame(SDL_Renderer* renderer) {
MTL::RenderPassDescriptor* current_render_pass = mctx.framebuffers[0].render_pass_descriptor;
ImGui_ImplMetal_NewFrame(current_render_pass);
}
Expand Down
1 change: 0 additions & 1 deletion src/graphic/Fast3D/gfx_metal.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ ImTextureID gfx_metal_get_texture_by_id(int id);
bool Metal_IsSupported();

bool Metal_Init(SDL_Renderer* renderer);
void Metal_SetupFrame(SDL_Renderer* renderer);
void Metal_NewFrame(SDL_Renderer* renderer);
void Metal_SetupFloatingFrame();
void Metal_RenderDrawData(ImDrawData* draw_data);
Expand Down
31 changes: 12 additions & 19 deletions src/graphic/Fast3D/gfx_pc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,6 @@ static int game_framebuffer_msaa_resolved;

uint32_t gfx_msaa_level = 1;

static bool dropped_frame;

static const std::unordered_map<Mtx*, MtxF>* current_mtx_replacements;

static float buf_vbo[MAX_BUFFERED * (32 * 3)]; // 3 vertices in a triangle and 32 floats per vtx
Expand Down Expand Up @@ -4123,8 +4121,15 @@ struct GfxRenderingAPI* gfx_get_current_rendering_api() {
return gfx_rapi;
}

void gfx_start_frame() {
void gfx_handle_window_events() {
gfx_wapi->handle_events();
}

bool gfx_is_frame_ready() {
return gfx_wapi->is_frame_ready();
}

void gfx_start_frame() {
gfx_wapi->get_dimensions(&gfx_current_window_dimensions.width, &gfx_current_window_dimensions.height,
&gfx_current_window_position_x, &gfx_current_window_position_y);
if (gfx_current_dimensions.height == 0) {
Expand Down Expand Up @@ -4184,20 +4189,11 @@ void gfx_start_frame() {
GfxExecStack g_exec_stack = {};

void gfx_run(Gfx* commands, const std::unordered_map<Mtx*, MtxF>& mtx_replacements) {
Ship::Context::GetInstance()->GetWindow()->GetGui()->SetupRendererFrame();

gfx_sp_reset();

get_pixel_depth_pending.clear();
get_pixel_depth_cached.clear();

if (!gfx_wapi->start_frame()) {
dropped_frame = true;
Ship::Context::GetInstance()->GetWindow()->GetGui()->Draw();
return;
}
dropped_frame = false;

current_mtx_replacements = &mtx_replacements;

gfx_rapi->update_framebuffer_parameters(0, gfx_current_window_dimensions.width,
Expand Down Expand Up @@ -4261,16 +4257,13 @@ void gfx_run(Gfx* commands, const std::unordered_map<Mtx*, MtxF>& mtx_replacemen

assert(0 && "active framebuffer was never reset back to original");
}
Ship::Context::GetInstance()->GetWindow()->GetGui()->Draw();
gfx_rapi->end_frame();
gfx_wapi->swap_buffers_begin();
}

void gfx_end_frame() {
if (!dropped_frame) {
gfx_rapi->finish_render();
gfx_wapi->swap_buffers_end();
}
gfx_rapi->end_frame();
gfx_wapi->swap_buffers_begin();
gfx_rapi->finish_render();
gfx_wapi->swap_buffers_end();
}

void gfx_set_target_ucode(UcodeHandlers ucode) {
Expand Down
2 changes: 2 additions & 0 deletions src/graphic/Fast3D/gfx_pc.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,8 @@ void gfx_start_frame();

// Since this function is "exposted" to the games, it needs to take a normal Gfx
void gfx_run(Gfx* commands, const std::unordered_map<Mtx*, MtxF>& mtx_replacements);
void gfx_handle_window_events();
bool gfx_is_frame_ready();
void gfx_end_frame();
void gfx_set_target_ucode(UcodeHandlers ucode);
void gfx_set_target_fps(int);
Expand Down
4 changes: 2 additions & 2 deletions src/graphic/Fast3D/gfx_sdl2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -600,7 +600,7 @@ static void gfx_sdl_handle_events() {
}
}

static bool gfx_sdl_start_frame() {
static bool gfx_sdl_is_frame_ready() {
return true;
}

Expand Down Expand Up @@ -709,7 +709,7 @@ struct GfxWindowManagerAPI gfx_sdl = { gfx_sdl_init,
gfx_sdl_is_mouse_captured,
gfx_sdl_get_dimensions,
gfx_sdl_handle_events,
gfx_sdl_start_frame,
gfx_sdl_is_frame_ready,
gfx_sdl_swap_buffers_begin,
gfx_sdl_swap_buffers_end,
gfx_sdl_get_time,
Expand Down
2 changes: 1 addition & 1 deletion src/graphic/Fast3D/gfx_window_manager_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ struct GfxWindowManagerAPI {
bool (*is_mouse_captured)();
void (*get_dimensions)(uint32_t* width, uint32_t* height, int32_t* posX, int32_t* posY);
void (*handle_events)();
bool (*start_frame)();
bool (*is_frame_ready)();
void (*swap_buffers_begin)();
void (*swap_buffers_end)();
double (*get_time)(); // For debug
Expand Down
2 changes: 2 additions & 0 deletions src/window/Window.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ class Window {
virtual void Close() = 0;
virtual void StartFrame() = 0;
virtual void EndFrame() = 0;
virtual bool IsFrameReady() = 0;
virtual void HandleEvents() = 0;
virtual void SetCursorVisibility(bool visible) = 0;
virtual uint32_t GetWidth() = 0;
virtual uint32_t GetHeight() = 0;
Expand Down
40 changes: 24 additions & 16 deletions src/window/gui/Gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,7 @@ void Gui::EndFrame() {
ImGui::EndFrame();
}

void Gui::DrawGame() {
void Gui::CalculateGameViewport() {
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_ChildBorderSize, 0.0f);
Expand Down Expand Up @@ -617,10 +617,25 @@ void Gui::DrawGame() {
}
}

ImGui::End();
}

void Gui::DrawGame() {
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_ChildBorderSize, 0.0f);
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.0f, 0.0f, 0.0f, 0.0f));
ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize |
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoBackground;

ImGui::Begin("Main Game", nullptr, flags);
ImGui::PopStyleVar(3);
ImGui::PopStyleColor();

GetGameOverlay()->Draw();

mainPos = ImGui::GetWindowPos();
size = ImGui::GetContentRegionAvail();
ImVec2 mainPos = ImGui::GetWindowPos();
ImVec2 size = ImGui::GetContentRegionAvail();
ImVec2 pos = ImVec2(0, 0);
if (CVarGetInteger(CVAR_LOW_RES_MODE, 0) == 1) { // N64 Mode takes priority
const float sw = size.y * 320.0f / 240.0f;
Expand Down Expand Up @@ -695,11 +710,16 @@ void Gui::CheckSaveCvars() {
}
}

void Gui::Draw() {
void Gui::StartDraw() {
// Initialize the frame.
StartFrame();
// Draw the gui menus
DrawMenu();
// Calculate the available space the game can render to
CalculateGameViewport();
}

void Gui::EndDraw() {
// Draw the game framebuffer into ImGui
DrawGame();
// End the frame
Expand All @@ -710,18 +730,6 @@ void Gui::Draw() {
CheckSaveCvars();
}

void Gui::SetupRendererFrame() {
switch (Context::GetInstance()->GetWindow()->GetWindowBackend()) {
#ifdef __APPLE__
case WindowBackend::FAST3D_SDL_METAL:
Metal_SetupFrame(mImpl.Metal.Renderer);
break;
#endif
default:
break;
}
}

ImTextureID Gui::GetTextureById(int32_t id) {
#ifdef ENABLE_DX11
if (Context::GetInstance()->GetWindow()->GetWindowBackend() == WindowBackend::FAST3D_DXGI_DX11) {
Expand Down
5 changes: 3 additions & 2 deletions src/window/gui/Gui.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ class Gui {
~Gui();

void Init(GuiWindowInitData windowImpl);
void Draw();
void StartDraw();
void EndDraw();
void HandleWindowEvents(WindowEvent event);
void SetupRendererFrame();
void SaveConsoleVariablesNextFrame();
bool SupportsViewports();
ImGuiID GetMainGameWindowID();
Expand Down Expand Up @@ -112,6 +112,7 @@ class Gui {
void DrawFloatingWindows();
void DrawMenu();
void DrawGame();
void CalculateGameViewport();

void ImGuiBackendNewFrame();
void ImGuiWMNewFrame();
Expand Down
Loading