mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-27 16:02:37 +00:00
window: create Vulkan surface visible on main thread
This commit is contained in:
1 parent
c52bf450f5
commit
cfa140fb12
4 files changed
+27
-124
No files matched your search
@@ -1,30 +1,8 @@
|
|||||||
#include "SDL.h"
|
|
||||||
#include "SDL_error.h"
|
|
||||||
#include "SDL_events.h"
|
|
||||||
#include "SDL_gamecontroller.h"
|
|
||||||
#include "SDL_hints.h"
|
|
||||||
#include "SDL_joystick.h"
|
|
||||||
#include "SDL_keyboard.h"
|
|
||||||
#include "SDL_keycode.h"
|
|
||||||
#include "SDL_mouse.h"
|
|
||||||
#include "SDL_pixels.h"
|
|
||||||
#include "SDL_rwops.h"
|
|
||||||
#include "SDL_stdinc.h"
|
|
||||||
#include "SDL_surface.h"
|
|
||||||
#include "SDL_thread.h"
|
|
||||||
#include "SDL_touch.h"
|
|
||||||
#include "SDL_video.h"
|
|
||||||
#include "SDL_vulkan.h"
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/common.h"
|
#include "common/common.h"
|
||||||
#include "common/emulatorConfig.h"
|
|
||||||
#include "common/file.h"
|
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/profiler.h"
|
#include "common/profiler.h"
|
||||||
#include "common/stringUtils.h"
|
|
||||||
#include "common/systemInfo.h"
|
|
||||||
#include "common/threads.h"
|
#include "common/threads.h"
|
||||||
#include "common/timer.h"
|
|
||||||
#include "graphics/host_gpu/graphicContext.h"
|
#include "graphics/host_gpu/graphicContext.h"
|
||||||
#include "graphics/host_gpu/renderer/render.h"
|
#include "graphics/host_gpu/renderer/render.h"
|
||||||
#include "graphics/host_gpu/renderer/renderContext.h"
|
#include "graphics/host_gpu/renderer/renderContext.h"
|
||||||
@@ -34,19 +12,11 @@
|
|||||||
#include "graphics/presentation/presenter.h"
|
#include "graphics/presentation/presenter.h"
|
||||||
#include "graphics/presentation/videoOut.h"
|
#include "graphics/presentation/videoOut.h"
|
||||||
#include "graphics/presentation/window/windowInternal.h"
|
#include "graphics/presentation/window/windowInternal.h"
|
||||||
#include "libs/controller.h"
|
|
||||||
#include "loader/systemContent.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstring>
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <fmt/format.h>
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <vulkan/vk_platform.h>
|
#include <vulkan/vk_platform.h>
|
||||||
|
|
||||||
@@ -334,7 +304,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void Destroy();
|
void Destroy();
|
||||||
void RefreshSurfaceSize();
|
|
||||||
|
|
||||||
WindowContext& m_window;
|
WindowContext& m_window;
|
||||||
vk::SwapchainKHR m_handle = nullptr;
|
vk::SwapchainKHR m_handle = nullptr;
|
||||||
@@ -396,12 +365,12 @@ struct Presenter::Impl {
|
|||||||
|
|
||||||
void Swapchain::Create() {
|
void Swapchain::Create() {
|
||||||
auto& graphics = m_window.graphic_ctx;
|
auto& graphics = m_window.graphic_ctx;
|
||||||
EXIT_IF(graphics.screen_width == 0);
|
|
||||||
EXIT_IF(graphics.screen_height == 0);
|
|
||||||
EXIT_IF(graphics.device == nullptr);
|
EXIT_IF(graphics.device == nullptr);
|
||||||
EXIT_IF(m_window.surface == nullptr);
|
EXIT_IF(m_window.surface == nullptr);
|
||||||
|
|
||||||
Common::LockGuard lock(m_window.mutex);
|
Common::LockGuard lock(m_window.mutex);
|
||||||
|
EXIT_IF(graphics.screen_width == 0);
|
||||||
|
EXIT_IF(graphics.screen_height == 0);
|
||||||
const auto& surface = m_window.surface_capabilities;
|
const auto& surface = m_window.surface_capabilities;
|
||||||
EXIT_NOT_IMPLEMENTED(surface.formats.empty());
|
EXIT_NOT_IMPLEMENTED(surface.formats.empty());
|
||||||
|
|
||||||
@@ -554,30 +523,18 @@ void Swapchain::Destroy() {
|
|||||||
m_render_complete.clear();
|
m_render_complete.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Swapchain::RefreshSurfaceSize() {
|
|
||||||
int width = 0;
|
|
||||||
int height = 0;
|
|
||||||
SDL_Vulkan_GetDrawableSize(m_window.window, &width, &height);
|
|
||||||
if (width > 0 && height > 0) {
|
|
||||||
m_window.graphic_ctx.screen_width = static_cast<uint32_t>(width);
|
|
||||||
m_window.graphic_ctx.screen_height = static_cast<uint32_t>(height);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_window.RefreshSurfaceCapabilities();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Swapchain::Recreate(bool surface_lost) {
|
void Swapchain::Recreate(bool surface_lost) {
|
||||||
Destroy();
|
Destroy();
|
||||||
if (surface_lost) {
|
if (surface_lost) {
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
// Surface recreation goes through SDL_Vulkan_CreateSurface, which touches the
|
// Surface recreation goes through SDL_Vulkan_CreateSurface, which touches the
|
||||||
// window's view/layer and must run on the main thread on macOS.
|
// window's view/layer and must run on the main thread on macOS.
|
||||||
m_window.RunOnMainThread([this] { m_window.RecreateSurface(); }, true);
|
m_window.RunOnMainThread([this] { m_window.RecreateSurface(); });
|
||||||
#else
|
#else
|
||||||
m_window.RecreateSurface();
|
m_window.RecreateSurface();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
RefreshSurfaceSize();
|
m_window.RefreshSurfaceCapabilities();
|
||||||
Create();
|
Create();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -803,29 +760,6 @@ void Presenter::Present(Frame& frame, bool reuse) {
|
|||||||
KYTY_PROFILER_FUNCTION();
|
KYTY_PROFILER_FUNCTION();
|
||||||
m_impl->frames.ValidateForPresent(&frame, reuse);
|
m_impl->frames.ValidateForPresent(&frame, reuse);
|
||||||
|
|
||||||
auto& window = m_impl->window;
|
|
||||||
if (window.window_hidden) {
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
// AppKit traps if a window is shown off the main thread; marshal and wait so the
|
|
||||||
// swapchain below is recreated against a visible window.
|
|
||||||
window.RunOnMainThread(
|
|
||||||
[&window] {
|
|
||||||
window.UpdateIcon();
|
|
||||||
SDL_ShowWindow(window.window);
|
|
||||||
SDL_RaiseWindow(window.window);
|
|
||||||
},
|
|
||||||
true);
|
|
||||||
#else
|
|
||||||
window.UpdateIcon();
|
|
||||||
|
|
||||||
SDL_ShowWindow(window.window);
|
|
||||||
SDL_RaiseWindow(window.window);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
window.window_hidden = false;
|
|
||||||
m_impl->RecoverSwapchain(Swapchain::Status::Recreate);
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto ime_visual = GetImeVisualState();
|
const auto ime_visual = GetImeVisualState();
|
||||||
auto& swapchain = m_impl->swapchain;
|
auto& swapchain = m_impl->swapchain;
|
||||||
for (uint32_t attempt = 0; attempt < 2; attempt++) {
|
for (uint32_t attempt = 0; attempt < 2; attempt++) {
|
||||||
@@ -848,7 +782,7 @@ void Presenter::Present(Frame& frame, bool reuse) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_impl->presented_ime_revision.store(ime_visual.revision, std::memory_order_release);
|
m_impl->presented_ime_revision.store(ime_visual.revision, std::memory_order_release);
|
||||||
window.UpdateTitle();
|
m_impl->window.UpdateTitle();
|
||||||
m_impl->frames.Release(&frame, true);
|
m_impl->frames.Release(&frame, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/profiler.h"
|
#include "common/profiler.h"
|
||||||
#include "common/stringUtils.h"
|
#include "common/stringUtils.h"
|
||||||
#include "common/systemInfo.h"
|
|
||||||
#include "common/threads.h"
|
#include "common/threads.h"
|
||||||
#include "common/timer.h"
|
#include "common/timer.h"
|
||||||
#include "graphics/host_gpu/graphicContext.h"
|
#include "graphics/host_gpu/graphicContext.h"
|
||||||
@@ -1037,10 +1036,6 @@ void WindowContext::CreateVulkan() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(device_name, device_properties.deviceName, sizeof(device_name));
|
|
||||||
std::snprintf(processor_name, sizeof(processor_name), "%s",
|
|
||||||
Common::GetSystemInfo().ProcessorName.c_str());
|
|
||||||
|
|
||||||
VulkanInitSubgroupSizeControl(graphic_ctx.physical_device, graphic_ctx);
|
VulkanInitSubgroupSizeControl(graphic_ctx.physical_device, graphic_ctx);
|
||||||
|
|
||||||
graphic_ctx.device = VulkanCreateDevice(graphic_ctx.physical_device, r, queue_family,
|
graphic_ctx.device = VulkanCreateDevice(graphic_ctx.physical_device, r, queue_family,
|
||||||
@@ -1079,7 +1074,6 @@ void WindowContext::RecreateSurface() {
|
|||||||
EXIT("Could not recreate the Vulkan surface: %s\n", SDL_GetError());
|
EXIT("Could not recreate the Vulkan surface: %s\n", SDL_GetError());
|
||||||
}
|
}
|
||||||
surface = native_surface;
|
surface = native_surface;
|
||||||
RefreshSurfaceCapabilities();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowContext::~WindowContext() {
|
WindowContext::~WindowContext() {
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
#include "common/file.h"
|
#include "common/file.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/profiler.h"
|
#include "common/profiler.h"
|
||||||
#include "common/stringUtils.h"
|
|
||||||
#include "common/systemInfo.h"
|
#include "common/systemInfo.h"
|
||||||
#include "common/threads.h"
|
#include "common/threads.h"
|
||||||
#include "common/timer.h"
|
#include "common/timer.h"
|
||||||
@@ -39,21 +38,18 @@
|
|||||||
#include "libs/controller.h"
|
#include "libs/controller.h"
|
||||||
#include "loader/systemContent.h"
|
#include "loader/systemContent.h"
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <vulkan/vk_platform.h>
|
#include <vulkan/vk_platform.h>
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
#define STBI_NO_SIMD
|
#define STBI_NO_SIMD
|
||||||
#include "stb_image.h"
|
#include "stb_image.h"
|
||||||
|
|
||||||
#include <fmt/format.h>
|
|
||||||
|
|
||||||
// IWYU pragma: no_include <intrin.h>
|
// IWYU pragma: no_include <intrin.h>
|
||||||
|
|
||||||
#define KYTY_ENABLE_DEBUG_PRINTF
|
#define KYTY_ENABLE_DEBUG_PRINTF
|
||||||
@@ -197,8 +193,6 @@ std::unique_ptr<WindowContext> g_window;
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
constexpr const char* KYTY_SDL_WINDOW_CAPTION = "Game";
|
constexpr const char* KYTY_SDL_WINDOW_CAPTION = "Game";
|
||||||
constexpr uint32_t KYTY_SDL_WINDOW_FLAGS =
|
|
||||||
(static_cast<uint32_t>(SDL_WINDOW_HIDDEN) | static_cast<uint32_t>(SDL_WINDOW_VULKAN));
|
|
||||||
constexpr int KYTY_SDL_WINDOWPOS_CENTERED = SDL_WINDOWPOS_CENTERED; /*NOLINT(hicpp-signed-bitwise)*/
|
constexpr int KYTY_SDL_WINDOWPOS_CENTERED = SDL_WINDOWPOS_CENTERED; /*NOLINT(hicpp-signed-bitwise)*/
|
||||||
|
|
||||||
static void SetPause(WindowLoopState& game, bool flag) {
|
static void SetPause(WindowLoopState& game, bool flag) {
|
||||||
@@ -407,6 +401,7 @@ static void GameEventDidEnterForeground(WindowLoopState& game) {
|
|||||||
|
|
||||||
void WindowContext::Resize(uint32_t new_width, uint32_t new_height) {
|
void WindowContext::Resize(uint32_t new_width, uint32_t new_height) {
|
||||||
EXIT_IF(new_width == 0 || new_height == 0);
|
EXIT_IF(new_width == 0 || new_height == 0);
|
||||||
|
Common::LockGuard lock(mutex);
|
||||||
graphic_ctx.screen_width = new_width;
|
graphic_ctx.screen_width = new_width;
|
||||||
graphic_ctx.screen_height = new_height;
|
graphic_ctx.screen_height = new_height;
|
||||||
}
|
}
|
||||||
@@ -728,8 +723,7 @@ void WindowContext::ProcessEvent(double time_s) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
void WindowContext::RunOnMainThread(std::function<void()> task) {
|
||||||
void WindowContext::RunOnMainThread(std::function<void()> task, bool wait) {
|
|
||||||
if (Common::Thread::IsMainThread()) {
|
if (Common::Thread::IsMainThread()) {
|
||||||
task();
|
task();
|
||||||
return;
|
return;
|
||||||
@@ -747,9 +741,6 @@ void WindowContext::RunOnMainThread(std::function<void()> task, bool wait) {
|
|||||||
event.type = SDL_USEREVENT;
|
event.type = SDL_USEREVENT;
|
||||||
SDL_PushEvent(&event);
|
SDL_PushEvent(&event);
|
||||||
|
|
||||||
if (!wait) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Common::LockGuard lock(main_task_mutex);
|
Common::LockGuard lock(main_task_mutex);
|
||||||
while (main_tasks_run < ticket) {
|
while (main_tasks_run < ticket) {
|
||||||
main_task_done.Wait(&main_task_mutex);
|
main_task_done.Wait(&main_task_mutex);
|
||||||
@@ -772,7 +763,6 @@ void WindowContext::DrainMainThreadTasks() {
|
|||||||
main_tasks_run += tasks.size();
|
main_tasks_run += tasks.size();
|
||||||
main_task_done.SignalAll();
|
main_task_done.SignalAll();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void WindowContext::Run() {
|
void WindowContext::Run() {
|
||||||
Common::Timer timer;
|
Common::Timer timer;
|
||||||
@@ -783,9 +773,7 @@ void WindowContext::Run() {
|
|||||||
loop.paused.store(false, std::memory_order_release);
|
loop.paused.store(false, std::memory_order_release);
|
||||||
|
|
||||||
while (!loop.need_exit) {
|
while (!loop.need_exit) {
|
||||||
#if defined(__APPLE__)
|
|
||||||
DrainMainThreadTasks();
|
DrainMainThreadTasks();
|
||||||
#endif
|
|
||||||
if (loop.paused.load(std::memory_order_acquire)) {
|
if (loop.paused.load(std::memory_order_acquire)) {
|
||||||
if (!timer.IsPaused()) {
|
if (!timer.IsPaused()) {
|
||||||
timer.Pause();
|
timer.Pause();
|
||||||
@@ -821,10 +809,7 @@ static void WindowCreate(WindowContext& context) {
|
|||||||
|
|
||||||
LOGF("WindowCreate(): width = %d, height = %d\n", width, height);
|
LOGF("WindowCreate(): width = %d, height = %d\n", width, height);
|
||||||
|
|
||||||
uint32_t window_flags = KYTY_SDL_WINDOW_FLAGS;
|
uint32_t window_flags = WindowContext::InitialWindowFlags(Config::FullscreenEnabled());
|
||||||
if (Config::FullscreenEnabled()) {
|
|
||||||
window_flags |= static_cast<uint32_t>(SDL_WINDOW_FULLSCREEN_DESKTOP);
|
|
||||||
}
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
// macOS 26 window chrome (CoreUI asset decode, SwiftUI titlebar) has been observed
|
// macOS 26 window chrome (CoreUI asset decode, SwiftUI titlebar) has been observed
|
||||||
// throwing NSExceptions under Rosetta during the first CATransaction commit. A
|
// throwing NSExceptions under Rosetta during the first CATransaction commit. A
|
||||||
@@ -836,13 +821,20 @@ static void WindowCreate(WindowContext& context) {
|
|||||||
context.window = SDL_CreateWindow(KYTY_SDL_WINDOW_CAPTION, KYTY_SDL_WINDOWPOS_CENTERED,
|
context.window = SDL_CreateWindow(KYTY_SDL_WINDOW_CAPTION, KYTY_SDL_WINDOWPOS_CENTERED,
|
||||||
KYTY_SDL_WINDOWPOS_CENTERED, width, height, window_flags);
|
KYTY_SDL_WINDOWPOS_CENTERED, width, height, window_flags);
|
||||||
|
|
||||||
context.window_hidden = true;
|
|
||||||
|
|
||||||
if (context.window == nullptr) {
|
if (context.window == nullptr) {
|
||||||
EXIT("%s\n", SDL_GetError());
|
EXIT("%s\n", SDL_GetError());
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_SetWindowResizable(context.window, SDL_FALSE);
|
SDL_SetWindowResizable(context.window, SDL_FALSE);
|
||||||
|
context.UpdateIcon();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t WindowContext::InitialWindowFlags(bool fullscreen) noexcept {
|
||||||
|
auto flags = static_cast<uint32_t>(SDL_WINDOW_VULKAN);
|
||||||
|
if (fullscreen) {
|
||||||
|
flags |= static_cast<uint32_t>(SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||||
|
}
|
||||||
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
Presenter& WindowInit(uint32_t width, uint32_t height) {
|
Presenter& WindowInit(uint32_t width, uint32_t height) {
|
||||||
@@ -959,6 +951,7 @@ void WindowContext::UpdateTitle() {
|
|||||||
Loader::SystemContentParamSfoGetString("TITLE_ID", title_id, sizeof(title_id));
|
Loader::SystemContentParamSfoGetString("TITLE_ID", title_id, sizeof(title_id));
|
||||||
static bool has_app_ver =
|
static bool has_app_ver =
|
||||||
Loader::SystemContentParamSfoGetString("APP_VER", app_ver, sizeof(app_ver));
|
Loader::SystemContentParamSfoGetString("APP_VER", app_ver, sizeof(app_ver));
|
||||||
|
static const std::string processor_name = Common::GetSystemInfo().ProcessorName;
|
||||||
static uint64_t fps_start = Common::Timer::QueryPerformanceCounter();
|
static uint64_t fps_start = Common::Timer::QueryPerformanceCounter();
|
||||||
static uint64_t frame_num = 0;
|
static uint64_t frame_num = 0;
|
||||||
static uint64_t fps_frames = 0;
|
static uint64_t fps_frames = 0;
|
||||||
@@ -983,19 +976,14 @@ void WindowContext::UpdateTitle() {
|
|||||||
fps_frames = 0;
|
fps_frames = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto fps = fmt::format(
|
const auto* device_name = graphic_ctx.GetPhysicalDeviceProperties().deviceName.data();
|
||||||
|
auto text = fmt::format(
|
||||||
"[{} | {}] {}{}{}{}{}{}[{}] [{}], frame: {}, fps: {:f}", KYTY_BUILD_LABEL, build_type,
|
"[{} | {}] {}{}{}{}{}{}[{}] [{}], frame: {}, fps: {:f}", KYTY_BUILD_LABEL, build_type,
|
||||||
(has_title ? title : ""), (has_title ? ", " : ""), (has_title_id ? title_id : ""),
|
(has_title ? title : ""), (has_title ? ", " : ""), (has_title_id ? title_id : ""),
|
||||||
(has_title_id ? ", " : ""), (has_app_ver ? app_ver : ""), (has_app_ver ? " " : ""),
|
(has_title_id ? ", " : ""), (has_app_ver ? app_ver : ""), (has_app_ver ? " " : ""),
|
||||||
device_name, processor_name, frame_num, current_fps);
|
device_name, processor_name, frame_num, current_fps);
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
RunOnMainThread([this, text = std::move(text)] { SDL_SetWindowTitle(window, text.c_str()); });
|
||||||
// AppKit traps on title changes off the main thread; fire-and-forget keeps present pacing.
|
|
||||||
RunOnMainThread([this, fps = std::move(fps)] { SDL_SetWindowTitle(window, fps.c_str()); },
|
|
||||||
false);
|
|
||||||
#else
|
|
||||||
SDL_SetWindowTitle(window, fps.c_str());
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Libs::Graphics
|
} // namespace Libs::Graphics
|
||||||
@@ -9,13 +9,10 @@
|
|||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
#include <functional>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Libs::Graphics {
|
namespace Libs::Graphics {
|
||||||
|
|
||||||
class Presenter;
|
class Presenter;
|
||||||
@@ -39,6 +36,7 @@ struct WindowContext {
|
|||||||
KYTY_CLASS_NO_COPY(WindowContext);
|
KYTY_CLASS_NO_COPY(WindowContext);
|
||||||
|
|
||||||
[[nodiscard]] static vk::PhysicalDeviceVulkan13Features RequiredVulkan13Features() noexcept;
|
[[nodiscard]] static vk::PhysicalDeviceVulkan13Features RequiredVulkan13Features() noexcept;
|
||||||
|
[[nodiscard]] static uint32_t InitialWindowFlags(bool fullscreen) noexcept;
|
||||||
void CreateVulkan();
|
void CreateVulkan();
|
||||||
void RecreateSurface();
|
void RecreateSurface();
|
||||||
void RefreshSurfaceCapabilities();
|
void RefreshSurfaceCapabilities();
|
||||||
@@ -49,36 +47,25 @@ struct WindowContext {
|
|||||||
void ProcessDisplayEvent(const SDL_DisplayEvent& event);
|
void ProcessDisplayEvent(const SDL_DisplayEvent& event);
|
||||||
void ProcessEvent(double time_seconds);
|
void ProcessEvent(double time_seconds);
|
||||||
void Run();
|
void Run();
|
||||||
|
// SDL window operations must complete on the main thread.
|
||||||
#if defined(__APPLE__)
|
void RunOnMainThread(std::function<void()> task);
|
||||||
// AppKit only allows window operations (show, icon, title, view/layer changes) on the
|
|
||||||
// main thread; the present thread marshals them through the SDL main loop with these.
|
|
||||||
// wait=true blocks until the task has run on the main thread.
|
|
||||||
void RunOnMainThread(std::function<void()> task, bool wait);
|
|
||||||
void DrainMainThreadTasks();
|
void DrainMainThreadTasks();
|
||||||
#endif
|
|
||||||
|
|
||||||
GraphicContext graphic_ctx;
|
GraphicContext graphic_ctx;
|
||||||
SDL_Window* window = nullptr;
|
SDL_Window* window = nullptr;
|
||||||
bool window_hidden = true;
|
|
||||||
vk::SurfaceKHR surface = nullptr;
|
vk::SurfaceKHR surface = nullptr;
|
||||||
SurfaceCapabilities surface_capabilities;
|
SurfaceCapabilities surface_capabilities;
|
||||||
std::unique_ptr<RenderContext> render_context;
|
std::unique_ptr<RenderContext> render_context;
|
||||||
std::unique_ptr<Presenter> presenter;
|
std::unique_ptr<Presenter> presenter;
|
||||||
WindowLoopState loop;
|
WindowLoopState loop;
|
||||||
|
|
||||||
char device_name[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE] = {0};
|
|
||||||
char processor_name[64] = {0};
|
|
||||||
|
|
||||||
Common::Mutex mutex;
|
Common::Mutex mutex;
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
Common::Mutex main_task_mutex;
|
Common::Mutex main_task_mutex;
|
||||||
Common::CondVar main_task_done;
|
Common::CondVar main_task_done;
|
||||||
std::vector<std::function<void()>> main_tasks; // guarded by main_task_mutex
|
std::vector<std::function<void()>> main_tasks; // guarded by main_task_mutex
|
||||||
uint64_t main_tasks_queued = 0; // guarded by main_task_mutex
|
uint64_t main_tasks_queued = 0; // guarded by main_task_mutex
|
||||||
uint64_t main_tasks_run = 0; // guarded by main_task_mutex
|
uint64_t main_tasks_run = 0; // guarded by main_task_mutex
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Libs::Graphics
|
} // namespace Libs::Graphics
|
||||||
|
|||||||
Reference in new issue
Block a user