Harden runtime flags and thin Apple/canvas seams

This commit is contained in:
2026-06-16 08:00:36 +02:00
parent 34e2747867
commit 2948e907bc
7 changed files with 157 additions and 50 deletions

View File

@@ -2,6 +2,7 @@
#include "shader.h"
#include <array>
#include <functional>
namespace pp::panopainter {
@@ -238,6 +239,14 @@ struct LegacyCanvasDrawMergePostDrawExecution {
std::function<void()> draw_current_modes;
};
struct LegacyCanvasDrawMergeSmaskFacesExecution {
std::function<void()> set_active_texture_unit;
std::function<void()> enable_blend;
std::function<void(int plane_index)> bind_face_texture;
std::function<void()> draw_face;
std::function<void(int plane_index)> unbind_face_texture;
};
[[nodiscard]] inline LegacyCanvasDrawMergeShaderExecution legacy_shader_manager_draw_merge_execution() noexcept
{
return {
@@ -631,4 +640,29 @@ inline void execute_legacy_canvas_draw_merge_post_draw(
execution.draw_current_modes();
}
inline void execute_legacy_canvas_draw_merge_smask_faces(
const LegacyCanvasDrawMergeTextureMaskUniforms& uniforms,
const glm::mat4& proj,
const glm::mat4& camera,
float layer_scale,
const std::array<glm::mat4, 6>& plane_transform,
const LegacyCanvasDrawMergeSmaskFacesExecution& execution)
{
setup_legacy_canvas_draw_merge_texture_mask_shader(uniforms);
execution.set_active_texture_unit();
execution.enable_blend();
for (int plane_index = 0; plane_index < 6; ++plane_index) {
auto plane_mvp = proj * camera *
glm::scale(glm::vec3(layer_scale)) *
plane_transform[plane_index] *
glm::translate(glm::vec3(0, 0, -1.f));
apply_legacy_canvas_draw_merge_mvp(plane_mvp);
execution.bind_face_texture(plane_index);
execution.draw_face();
execution.unbind_face_texture(plane_index);
}
}
} // namespace pp::panopainter

View File

@@ -31,6 +31,7 @@
#include <ctime>
#include <sstream>
#include <memory>
#include <atomic>
#include <stop_token>
#define WM_USER_CLOSE (WM_USER + 1)
@@ -50,9 +51,9 @@ std::map<kKey, int> vkey_map;
static wchar_t window_title[512];
std::jthread hmd_renderer;
int vr_frames = 0;
int running = -1;
int vr_running = 0;
std::atomic<int> vr_frames{0};
std::atomic<int> running{-1};
std::atomic_bool vr_running{false};
int gl_count = 0;
std::deque<std::packaged_task<void()>> main_tasklist;
@@ -233,8 +234,9 @@ void win32_update_stylus(float dt)
void win32_update_fps(int frames)
{
static wchar_t title_fps[512];
const int vr_fps = vr_frames.load(std::memory_order_relaxed);
if (App::I->vr_active)
swprintf_s(title_fps, L"%s - %d fps - %d vr fps", window_title, frames, vr_frames);
swprintf_s(title_fps, L"%s - %d fps - %d vr fps", window_title, frames, vr_fps);
else
swprintf_s(title_fps, L"%s - %d fps", window_title, frames);
@@ -547,7 +549,7 @@ bool win32_vr_start()
BT_SetTerminate();
LOG("start hmd render thread");
App::I->has_vr = true;
vr_running = true;
vr_running.store(true, std::memory_order_relaxed);
vive->on_analog_button = std::bind(&App::vr_analog, App::I, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3, std::placeholders::_4);
@@ -562,7 +564,7 @@ bool win32_vr_start()
auto t0 = GetTickCount64();
float one_sec_timer = 0;
int frames = 0;
while (!stop_token.stop_requested() && vr_running && running == 1 && vive->Valid())
while (!stop_token.stop_requested() && vr_running.load(std::memory_order_relaxed) && running.load(std::memory_order_relaxed) == 1 && vive->Valid())
{
std::unique_lock<std::mutex> lock(hmd_render_mutex);
auto t1 = GetTickCount64();
@@ -572,7 +574,7 @@ bool win32_vr_start()
if (one_sec_timer >= 1.f)
{
one_sec_timer = 0;
vr_frames = frames;
vr_frames.store(frames, std::memory_order_relaxed);
frames = 0;
}
frames++;
@@ -583,7 +585,7 @@ bool win32_vr_start()
App::I->vr_head = vive->m_pose;
App::I->vr_update(dt);
if (vr_running && vive->m_active)
if (vr_running.load(std::memory_order_relaxed) && vive->m_active)
{
App::I->render_task([] {
vive->Draw();
@@ -597,7 +599,7 @@ bool win32_vr_start()
}
App::I->vr_active = false;
App::I->has_vr = false;
vr_running = false;
vr_running.store(false, std::memory_order_relaxed);
vive->Terminate();
LOG("hmd renderer terminated");
});
@@ -608,7 +610,7 @@ void win32_vr_stop()
{
if (vive)
{
vr_running = false;
vr_running.store(false, std::memory_order_relaxed);
if (hmd_renderer.joinable())
{
hmd_renderer.request_stop();
@@ -937,7 +939,7 @@ int main(int argc, char** argv)
wglMakeCurrent(NULL, NULL);
running = 1;
running.store(1, std::memory_order_relaxed);
App::I->runtime().render_thread_start(*App::I);
App::I->runtime().ui_thread_start(*App::I);
@@ -985,14 +987,14 @@ int main(int argc, char** argv)
MSG msg;
LOG("start main loop");
while (running == 1)
while (running.load(std::memory_order_relaxed) == 1)
{
// If there any message in the queue process it
auto present = App::I->animate || App::I->redraw ?
PeekMessage(&msg, 0, 0, 0, PM_REMOVE) : GetMessage(&msg, 0, 0, 0);
if (msg.message == WM_QUIT)
running = 0;
running.store(0, std::memory_order_relaxed);
if (present)
{
@@ -1038,7 +1040,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
switch (msg)
{
case WM_USER_CLOSE:
running = 0;
running.store(0, std::memory_order_relaxed);
if (hmd_renderer.joinable())
{
hmd_renderer.request_stop();
@@ -1071,7 +1073,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
auto w = (float)LOWORD(lp);
auto h = (float)HIWORD(lp);
if (h != 0 && running == 1)
if (h != 0 && running.load(std::memory_order_relaxed) == 1)
{
App::I->ui_task_async([=]
{

View File

@@ -738,27 +738,32 @@ void NodeCanvas::draw()
m_canvas->modes[(int)kCanvasMode::MaskLine][0]->on_Draw(ortho_proj, proj, camera);
},
.draw_smask_faces = [&] {
pp::panopainter::setup_legacy_canvas_draw_merge_texture_mask_shader(
pp::panopainter::execute_legacy_canvas_draw_merge_smask_faces(
pp::panopainter::LegacyCanvasDrawMergeTextureMaskUniforms {
.texture_slot = 0,
.pattern_offset = m_outline_pan,
},
proj,
camera,
m_canvas->m_layers.size() + 500.f,
m_canvas->m_plane_transform,
{
.set_active_texture_unit = [&] {
set_active_texture_unit(0);
},
.enable_blend = [&] {
apply_node_canvas_capability(pp::renderer::gl::blend_state(), true);
},
.bind_face_texture = [&](int plane_index) {
m_canvas->m_smask.rtt(plane_index).bindTexture();
},
.draw_face = [&] {
m_face_plane.draw_fill();
},
.unbind_face_texture = [&](int plane_index) {
m_canvas->m_smask.rtt(plane_index).unbindTexture();
},
});
set_active_texture_unit(0);
apply_node_canvas_capability(pp::renderer::gl::blend_state(), true);
//draw the cube faces
for (int plane_index = 0; plane_index < 6; plane_index++)
{
auto plane_mvp = proj * camera *
glm::scale(glm::vec3(m_canvas->m_layers.size() + 500.f)) *
m_canvas->m_plane_transform[plane_index] *
glm::translate(glm::vec3(0, 0, -1.f));
pp::panopainter::apply_legacy_canvas_draw_merge_mvp(plane_mvp);
m_canvas->m_smask.rtt(plane_index).bindTexture();
m_face_plane.draw_fill();
m_canvas->m_smask.rtt(plane_index).unbindTexture();
}
},
.draw_grid_modes = [&] {
for (auto& mode : Canvas::modes[(int)kCanvasMode::Grid])

View File

@@ -132,25 +132,62 @@ struct RetainedLegacyGlfwWindowHooks final {
return types;
}
struct RetainedLegacyAppleState final {
#ifdef __IOS__
decltype(App::I->ios_view) ios_view = nullptr;
decltype(App::I->ios_app) ios_app = nullptr;
#elif defined(__OSX__)
decltype(App::I->osx_view) osx_view = nullptr;
decltype(App::I->osx_app) osx_app = nullptr;
#endif
pp::platform::PlatformStoragePaths storage_paths;
};
[[nodiscard]] RetainedLegacyAppleState& active_legacy_apple_state()
{
static RetainedLegacyAppleState state = [] {
RetainedLegacyAppleState retained;
#ifdef __IOS__
retained.ios_view = App::I->ios_view;
retained.ios_app = App::I->ios_app;
retained.storage_paths = {
App::I->data_path,
App::I->work_path,
App::I->rec_path,
App::I->tmp_path,
};
#elif defined(__OSX__)
retained.osx_view = App::I->osx_view;
retained.osx_app = App::I->osx_app;
retained.storage_paths = {
App::I->data_path,
App::I->work_path,
App::I->rec_path,
App::I->tmp_path,
};
#endif
return retained;
}();
return state;
}
[[nodiscard]] pp::platform::PlatformStoragePaths prepare_legacy_apple_storage_paths()
{
const auto& apple_state = active_legacy_apple_state();
#ifdef __IOS__
[App::I->ios_view init_dirs];
[apple_state.ios_view init_dirs];
#elif defined(__OSX__)
[App::I->osx_app init_dirs];
[apple_state.osx_app init_dirs];
#endif
return {
App::I->data_path,
App::I->work_path,
App::I->rec_path,
App::I->tmp_path,
};
return apple_state.storage_paths;
}
[[nodiscard]] pp::platform::apple::AppleDocumentPlatformServices& active_apple_document_platform_services()
{
#ifdef __IOS__
auto* const ios_view = App::I->ios_view;
const auto& apple_state = active_legacy_apple_state();
auto* const ios_view = apple_state.ios_view;
auto* const ios_app = apple_state.ios_app;
static pp::platform::apple::AppleDocumentPlatformServices services(
pp::platform::PlatformFamily::ios,
[ios_view] {
@@ -173,8 +210,8 @@ struct RetainedLegacyGlfwWindowHooks final {
bridge.trigger_crash_test = [ios_view] {
[ios_view crash];
};
bridge.start_sonarpen = [ios_view] {
[App::I->ios_app sonarpen_start];
bridge.start_sonarpen = [ios_app] {
[ios_app sonarpen_start];
};
bridge.acquire_render_context = [ios_view] {
[ios_view async_lock];
@@ -224,8 +261,9 @@ struct RetainedLegacyGlfwWindowHooks final {
}());
return services;
#else
auto* const osx_view = App::I->osx_view;
auto* const osx_app = App::I->osx_app;
const auto& apple_state = active_legacy_apple_state();
auto* const osx_view = apple_state.osx_view;
auto* const osx_app = apple_state.osx_app;
static pp::platform::apple::AppleDocumentPlatformServices services(
pp::platform::PlatformFamily::macos,
[osx_view, osx_app] {