diff --git a/cmake/PanoPainterSources.cmake b/cmake/PanoPainterSources.cmake index 009f36c6..408a39d9 100644 --- a/cmake/PanoPainterSources.cmake +++ b/cmake/PanoPainterSources.cmake @@ -97,6 +97,7 @@ set(PP_PANOPAINTER_APP_SOURCES src/app_dialogs_info_openers.cpp src/app_events.cpp src/app_layout.cpp + src/app_layout_bootstrap.cpp src/app_layout_brush.cpp src/app_layout_draw_toolbar.cpp src/app_layout_ui_state.cpp diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index bae964b4..380e4672 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -80,13 +80,13 @@ What is still carrying too much live ownership: Current hotspot files: - `src/canvas.cpp`: 2645 lines -- `src/app_layout.cpp`: 229 lines +- `src/app_layout.cpp`: 125 lines - `src/canvas_modes.cpp`: 1798 lines - `src/node.cpp`: 1594 lines -- `src/main.cpp`: 390 lines +- `src/main.cpp`: 271 lines - `src/node_panel_brush.cpp`: 1197 lines - `src/node_stroke_preview.cpp`: 890 lines -- `src/node_canvas.cpp`: 831 lines +- `src/node_canvas.cpp`: 852 lines - `src/app.cpp`: 502 lines - `src/app_dialogs.cpp`: 142 lines @@ -135,7 +135,14 @@ Current architecture mismatches that must be treated as real blockers: `execute_legacy_canvas_draw_unmerged_node_canvas_shell(...)`, while the broader unmerged cache/viewport/background/composite pass setup now also routes through - `execute_legacy_canvas_draw_unmerged_node_canvas_pass(...)`. + `execute_legacy_canvas_draw_unmerged_node_canvas_pass(...)`, while + `NodeCanvas::draw()` setup, merged-pass shell, and unmerged-pass shell now + also route through `prepare_legacy_node_canvas_draw_setup(...)`, + `execute_legacy_canvas_draw_node_canvas_shell(...)`, + `execute_legacy_canvas_draw_merged_pass(...)`, and + `execute_legacy_canvas_draw_node_canvas_unmerged_pass(...)`, which + materially shortens the live `NodeCanvas::draw()` body even though the file + itself is still large. - `app_layout.cpp` and `app_dialogs.cpp` are still mixed shell/controller files rather than thin composition/binding surfaces, even though tools-menu binding plus nested panels/options submenu wiring now live in @@ -154,8 +161,9 @@ Current architecture mismatches that must be treated as real blockers: persisted floating/docked panel-state ownership now also live in `src/app_layout_ui_state.cpp`, while draw-toolbar binding now also lives in `src/app_layout_draw_toolbar.cpp`, while brush-refresh now also lives in - `src/app_layout_brush.cpp`, and `src/app_layout.cpp` is now mostly - layout/bootstrap composition, while the + `src/app_layout_brush.cpp`, while layout bootstrap plus reload/load + continuation wiring now also lives in `src/app_layout_bootstrap.cpp`, and + `src/app_layout.cpp` is now mostly thin call-through entrypoints, while the informational overlay opener family now also lives in `src/app_dialogs_info_openers.cpp` and the corresponding `App::dialog_*` entrypoints are thinner, while the export/video/PPBR dialog family now also @@ -193,8 +201,9 @@ Current architecture mismatches that must be treated as real blockers: while the retained Win32 VR/HMD shell now also routes through `src/platform_windows/windows_vr_shell.h` instead of staying inline in `src/main.cpp`, while RenderDoc startup/frame capture, SHCore DPI bootstrap, - Win32 error-string conversion, and the GL debug pre/post callbacks now also - live in `src/platform_windows/windows_bootstrap_helpers.cpp` instead of + Win32 error-string conversion, the GL debug pre/post callbacks, and the WMI + startup probe now also live in + `src/platform_windows/windows_bootstrap_helpers.cpp` instead of `src/main.cpp`, while Win32 lifecycle running-state, close/shutdown sequencing, FPS title update/wakeup posting, stylus frame update, window preference save, and VR lifecycle wrappers now also live in diff --git a/docs/modernization/tasks.md b/docs/modernization/tasks.md index c36875ee..8abac284 100644 --- a/docs/modernization/tasks.md +++ b/docs/modernization/tasks.md @@ -235,6 +235,13 @@ Current slice: `execute_legacy_canvas_draw_unmerged_node_canvas_pass(...)`, which removes another coherent outer-shell block even though the broader node draw loop still lives in `src/node_canvas.cpp`. +- `NodeCanvas::draw()` setup, merged-pass shell, and unmerged-pass shell now + also route through `prepare_legacy_node_canvas_draw_setup(...)`, + `execute_legacy_canvas_draw_node_canvas_shell(...)`, + `execute_legacy_canvas_draw_merged_pass(...)`, and + `execute_legacy_canvas_draw_node_canvas_unmerged_pass(...)`, which + materially shortens the live `NodeCanvas::draw()` body even though the file + itself is still large. Write scope: - `src/node_stroke_preview.cpp` @@ -313,7 +320,7 @@ targets look like helpers under one old monolith. Status: In Progress Why now: -`src/app_layout.cpp` is still a 229-line mixed file that builds menus, +`src/app_layout.cpp` is still a 125-line mixed file that builds menus, attaches callbacks, computes planner inputs, and mutates UI state directly. Current slice: @@ -348,6 +355,9 @@ Current slice: layout/bootstrap composition. - Brush-refresh now also lives in `src/app_layout_brush.cpp`, and `src/app_layout.cpp` is down to the remaining layout/bootstrap composition. +- Layout bootstrap plus reload/load continuation wiring now also lives in + `src/app_layout_bootstrap.cpp`, and `src/app_layout.cpp` is down to thin + call-through entrypoints plus the remaining local helper pocket. Write scope: - `src/app_layout.cpp` @@ -505,6 +515,9 @@ Current slice: conversion, `UnadjustWindowRectEx`, and GL debug pre/post callbacks now also live in `src/platform_windows/windows_bootstrap_helpers.cpp` instead of `src/main.cpp` +- the WMI startup probe now also lives in + `src/platform_windows/windows_bootstrap_helpers.cpp` instead of + `src/main.cpp` - Win32 lifecycle running-state, close/shutdown handling, FPS title update and wakeup posting, stylus frame update, window preference save, and VR lifecycle wrappers now also live in diff --git a/src/app_layout.cpp b/src/app_layout.cpp index b3b3e45a..87c0da71 100644 --- a/src/app_layout.cpp +++ b/src/app_layout.cpp @@ -1,11 +1,6 @@ #include "pch.h" #include "app.h" -#include "node_panel_grid.h" -#include "node_icon.h" -#include "node_dialog_open.h" #include "node_text.h" -#include "node_progress_bar.h" -#include "node_dialog_picker.h" #include "node_panel_floating.h" #include "app_core/about_menu.h" #include "app_core/app_preferences.h" @@ -18,10 +13,6 @@ #include "legacy_document_layer_services.h" #include "legacy_preference_storage.h" #include "font.h" -#include "node_remote_page.h" -#include "node_shorcuts.h" - -#include namespace pp::panopainter { void bind_legacy_main_toolbar(App& app); @@ -30,6 +21,7 @@ void bind_legacy_edit_menu(App& app); void bind_legacy_about_menu(App& app); void bind_legacy_layer_menu(App& app); void bind_legacy_tools_menu(App& app); +void init_layout_bootstrap(App& app); } namespace { @@ -120,137 +112,7 @@ void App::init_menu_layer() void App::initLayout() { - LOG("initializing layout statics"); - NodeBorder::static_init(); - NodeImage::static_init(); - NodeIcon::static_init(); - NodeStrokePreview::static_init(); - - static std::vector> saved_layers; - layout.on_reloading = [&] { - saved_layers = std::move(Canvas::I->m_layers); - ui_save(); - NodeStrokePreview::empty_queue(); - }; - - layout.on_loaded = [&] (bool reloaded) { - LOG("initializing layout updating after load %d x %d zoom %f", (int)width, (int)height, zoom); - layout[main_id]->update(width, height, zoom); - - LOG("initializing layout components"); - - init_sidebar(); - - if (reloaded) - { - for (const auto& l : saved_layers) - layers->add_layer(l->m_name.c_str(), false, true, l); - } - else - { - layers->add_layer("Default", false, true); - Canvas::I->m_unsaved = false; - } - - init_toolbar_draw(); - init_toolbar_main(); - init_menu_file(); - init_menu_edit(); - init_menu_layer(); - init_menu_tools(); - init_menu_about(); - - // set version string - if (auto* version_label = layout[main_id]->find("version")) - { - version_label->set_text(g_version); - } - - const auto renderer_features = ShaderManager::render_device_features(); - const auto renderer_diagnostics = pp::app::plan_renderer_diagnostics({ - .framebuffer_fetch = renderer_features.framebuffer_fetch, - .float32_render_targets = renderer_features.float32_render_targets, - .float32_linear_filtering = renderer_features.float32_linear_filtering, - .float16_render_targets = renderer_features.float16_render_targets, - }); - - if (auto x = layout[main_id]->find("ext-fbf")) - { - x->m_color = renderer_diagnostics.framebuffer_fetch.supported ? - glm::vec4(0, 1, 0, 1) : - glm::vec4(1, 0, 0, 1); - } - - if (auto x = layout[main_id]->find("ext-flt")) - { - if (renderer_diagnostics.floating_point_targets.supported) - { - if (auto t = x->find("ext-flt-text")) - { - t->set_text(std::string(renderer_diagnostics.floating_point_targets.label)); - } - x->m_color = glm::vec4(0, 1, 0, 1); - } - else - { - x->m_color = glm::vec4(1, 0, 0, 1); - } - } - - dialog_whatsnew(false); - - brush_update(true, true); - - // hacky thing to make the toolbar buttons not steal events when moving cursor fast - if (auto* toolbar = layout[main_id]->find("toolbar")) - toolbar->m_flood_events = true; - - NodeImage* n = new NodeImage; - n->m_path = "data/ui/p-black.png"; - n->m_tex_id = const_hash("data/ui/p-black.png"); - n->SetSize(30, 45); - n->create(); - - NodeButtonCustom* butt = new NodeButtonCustom; - butt->create(); - butt->add_child(n); - butt->SetPositioning(YGPositionTypeAbsolute); - butt->set_color({ 0, 0, 0, 0 }); - //n->SetPosition(100, 100); - YGNodeStyleSetPosition(butt->y_node, YGEdgeBottom, 8); - YGNodeStyleSetPosition(butt->y_node, YGEdgeLeft, 10); - //butt->SetSize(30, 45); - layout[main_id]->add_child(butt); - - butt->on_click = [this](Node*){ - toggle_ui(); - }; - - ui_restore(); - - redraw = true; - }; - - LOG("initializing layout xml"); - if (layout.m_loaded) - { - LOG("restore layout"); - layout.restore_context(); - } - else - layout.load("data/layout.xml"); - LOG("initializing layout completed"); - - LOG("initializing layout designer xml"); - layout_designer.on_loaded = [&](bool reloaded) { - layout_designer.create(); - //layout_designer[main_id]->add_child(layout_designer.instantiate("shortcuts")); - auto p = layout_designer[main_id]->add_child(); - //p->SetPosition(300, 300); - //p->SetSize(600, 400); - //p->m_container->add_child(); - }; - //layout_designer.load("data/dialogs/shortcuts.xml"); + pp::panopainter::init_layout_bootstrap(*this); } void App::set_ui_scale(float scale) diff --git a/src/app_layout_bootstrap.cpp b/src/app_layout_bootstrap.cpp new file mode 100644 index 00000000..d6e731dc --- /dev/null +++ b/src/app_layout_bootstrap.cpp @@ -0,0 +1,148 @@ +#include "pch.h" +#include "app.h" +#include "node_border.h" +#include "node_button_custom.h" +#include "node_icon.h" +#include "node_image.h" +#include "node_shorcuts.h" +#include "node_stroke_preview.h" +#include "node_text.h" +#include "app_core/app_status.h" + +#include + +namespace { + +std::vector> saved_layers; + +void capture_layout_reload_state(App& app) +{ + saved_layers = std::move(Canvas::I->m_layers); + app.ui_save(); + NodeStrokePreview::empty_queue(); +} + +void apply_layout_loaded_state(App& app, bool reloaded) +{ + LOG("initializing layout updating after load %d x %d zoom %f", (int)app.width, (int)app.height, app.zoom); + app.layout[app.main_id]->update(app.width, app.height, app.zoom); + + LOG("initializing layout components"); + app.init_sidebar(); + + if (reloaded) { + for (const auto& layer : saved_layers) + app.layers->add_layer(layer->m_name.c_str(), false, true, layer); + } else { + app.layers->add_layer("Default", false, true); + Canvas::I->m_unsaved = false; + } + + app.init_toolbar_draw(); + app.init_toolbar_main(); + app.init_menu_file(); + app.init_menu_edit(); + app.init_menu_layer(); + app.init_menu_tools(); + app.init_menu_about(); + + if (auto* version_label = app.layout[app.main_id]->find("version")) { + version_label->set_text(g_version); + } + + const auto renderer_features = ShaderManager::render_device_features(); + const auto renderer_diagnostics = pp::app::plan_renderer_diagnostics({ + .framebuffer_fetch = renderer_features.framebuffer_fetch, + .float32_render_targets = renderer_features.float32_render_targets, + .float32_linear_filtering = renderer_features.float32_linear_filtering, + .float16_render_targets = renderer_features.float16_render_targets, + }); + + if (auto* indicator = app.layout[app.main_id]->find("ext-fbf")) { + indicator->m_color = renderer_diagnostics.framebuffer_fetch.supported + ? glm::vec4(0, 1, 0, 1) + : glm::vec4(1, 0, 0, 1); + } + + if (auto* indicator = app.layout[app.main_id]->find("ext-flt")) { + if (renderer_diagnostics.floating_point_targets.supported) { + if (auto* text = indicator->find("ext-flt-text")) + text->set_text(std::string(renderer_diagnostics.floating_point_targets.label)); + indicator->m_color = glm::vec4(0, 1, 0, 1); + } else { + indicator->m_color = glm::vec4(1, 0, 0, 1); + } + } + + app.dialog_whatsnew(false); + app.brush_update(true, true); + + if (auto* toolbar = app.layout[app.main_id]->find("toolbar")) + toolbar->m_flood_events = true; + + auto* toggle_button = new NodeImage; + toggle_button->m_path = "data/ui/p-black.png"; + toggle_button->m_tex_id = const_hash("data/ui/p-black.png"); + toggle_button->SetSize(30, 45); + toggle_button->create(); + + auto* button = new NodeButtonCustom; + button->create(); + button->add_child(toggle_button); + button->SetPositioning(YGPositionTypeAbsolute); + button->set_color({ 0, 0, 0, 0 }); + YGNodeStyleSetPosition(button->y_node, YGEdgeBottom, 8); + YGNodeStyleSetPosition(button->y_node, YGEdgeLeft, 10); + app.layout[app.main_id]->add_child(button); + + button->on_click = [&app](Node*) { + app.toggle_ui(); + }; + + app.ui_restore(); + app.redraw = true; +} + +void init_layout_designer(App& app) +{ + app.layout_designer.on_loaded = [&app](bool) { + app.layout_designer.create(); + auto* shortcuts = app.layout_designer[app.main_id]->add_child(); + (void)shortcuts; + }; +} + +} // namespace + +namespace pp::panopainter { + +void init_layout_bootstrap(App& app) +{ + LOG("initializing layout statics"); + NodeBorder::static_init(); + NodeImage::static_init(); + NodeIcon::static_init(); + NodeStrokePreview::static_init(); + + app.layout.on_reloading = [&app] { + capture_layout_reload_state(app); + }; + + app.layout.on_loaded = [&app](bool reloaded) { + apply_layout_loaded_state(app, reloaded); + }; + + LOG("initializing layout xml"); + if (app.layout.m_loaded) { + LOG("restore layout"); + app.layout.restore_context(); + } else { + app.layout.load("data/layout.xml"); + } + LOG("initializing layout completed"); + + LOG("initializing layout designer xml"); + init_layout_designer(app); +} + +} // namespace pp::panopainter diff --git a/src/legacy_canvas_draw_merge_services.h b/src/legacy_canvas_draw_merge_services.h index 39a6a412..868539fa 100644 --- a/src/legacy_canvas_draw_merge_services.h +++ b/src/legacy_canvas_draw_merge_services.h @@ -1112,6 +1112,99 @@ inline void execute_legacy_canvas_draw_unmerged_node_canvas_shell( } } +template < + typename PrepareDensityRenderTarget, + typename PrepareStandardRenderTarget, + typename DrawMergedPass, + typename DrawUnmergedPass> +inline void execute_legacy_canvas_draw_node_canvas_shell( + bool use_density_render_target, + bool draw_merged, + PrepareDensityRenderTarget&& prepare_density_render_target, + PrepareStandardRenderTarget&& prepare_standard_render_target, + DrawMergedPass&& draw_merged_pass, + DrawUnmergedPass&& draw_unmerged_pass) +{ + if (use_density_render_target) { + prepare_density_render_target(); + } else { + prepare_standard_render_target(); + } + + if (draw_merged) { + draw_merged_pass(); + return; + } + + draw_unmerged_pass(); +} + +template +inline void prepare_legacy_node_canvas_draw_setup( + NodeCanvasT& node_canvas, + const glm::vec4& box, + const glm::ivec4& c, + const glm::mat4& proj, + const glm::mat4& camera) +{ + node_canvas.m_canvas->m_mv = camera; + node_canvas.m_canvas->m_proj = proj; + node_canvas.m_canvas->m_box = box; + node_canvas.m_canvas->m_vp = c; + + for (int plane_index = 0; plane_index < 6; plane_index++) { + node_canvas.m_canvas->m_plane_unproject[plane_index] = + glm::inverse(node_canvas.m_canvas->m_proj * node_canvas.m_canvas->m_mv * node_canvas.m_canvas->m_plane_transform[plane_index]); + node_canvas.m_canvas->m_plane_dir[plane_index] = + -(node_canvas.m_canvas->m_plane_transform[plane_index] * glm::vec4(node_canvas.m_canvas->m_plane_origin[plane_index], 1)); + node_canvas.m_canvas->m_plane_shape[plane_index] = + node_canvas.m_canvas->face_to_shape2D(plane_index); + } +} + +template < + typename NodeCanvasT, + typename ApplyCapability, + typename SetActiveTextureUnit, + typename DrawFacePlane> +inline void execute_legacy_canvas_draw_merged_pass( + NodeCanvasT& node_canvas, + const glm::mat4& proj, + const glm::mat4& camera, + ApplyCapability&& apply_node_canvas_capability, + SetActiveTextureUnit&& set_active_texture_unit, + DrawFacePlane&& draw_face_plane) +{ + execute_legacy_canvas_draw_merge_background_setup( + { + .draw_merged = true, + }, + { + .disable_blend = [&] { + apply_node_canvas_capability(pp::renderer::gl::blend_state(), false); + }, + .draw_checkerboard_plane = make_legacy_canvas_draw_merge_background_checkerboard_plane( + proj, + camera, + node_canvas.m_canvas->m_layers.size() + 500.f, + node_canvas.m_canvas->m_plane_transform, + std::forward(draw_face_plane)), + }); + + const auto draw_merged_texture_plane = make_legacy_canvas_draw_merge_layer_texture_draw( + &node_canvas.m_canvas->m_layers_merge, + &node_canvas.m_sampler, + &node_canvas.m_face_plane, + std::forward(set_active_texture_unit), + proj, + camera, + node_canvas.m_canvas->m_plane_transform); + + for (int plane_index = 0; plane_index < 6; plane_index++) { + draw_merged_texture_plane(plane_index); + } +} + template < typename NodeCanvasT, typename ApplyViewport, @@ -1219,6 +1312,63 @@ inline void execute_legacy_canvas_draw_unmerged_node_canvas_pass( }); } +template < + typename NodeCanvasT, + typename ApplyViewport, + typename ApplyCapability, + typename SetSampler, + typename MakeLayerPathExecution, + typename LogOnionRangeFailure> +inline void execute_legacy_canvas_draw_node_canvas_unmerged_pass( + NodeCanvasT& node_canvas, + bool use_blend, + bool copy_blend_destination, + const glm::mat4& proj, + const glm::mat4& camera, + const glm::mat4& layer_orientation, + const glm::ivec4& c, + ApplyViewport&& apply_node_canvas_viewport, + ApplyCapability&& apply_node_canvas_capability, + SetSampler&& set_sampler, + MakeLayerPathExecution&& make_layer_path_execution, + LogOnionRangeFailure&& log_onion_range_failure) +{ + const auto& brush = node_canvas.m_canvas->m_current_stroke->m_brush; + execute_legacy_canvas_draw_unmerged_node_canvas_pass( + node_canvas, + use_blend, + proj, + camera, + layer_orientation, + c, + std::forward(apply_node_canvas_viewport), + std::forward(apply_node_canvas_capability), + [&] { + node_canvas.m_face_plane.draw_fill(); + }, + std::forward(set_sampler), + [&](size_t layer_index, int plane_index, const glm::mat4& plane_mvp_z) { + return make_layer_path_execution( + layer_index, + plane_index, + plane_mvp_z, + brush.get(), + copy_blend_destination, + node_canvas.m_canvas->m_cam_fov < 20.f); + }, + [&] { + return make_legacy_canvas_draw_merge_cache_to_screen_checkerboard_plane( + proj, + camera, + node_canvas.m_canvas->m_layers.size() + 500.f, + node_canvas.m_canvas->m_plane_transform, + [&] { + node_canvas.m_face_plane.draw_fill(); + }); + }, + std::forward(log_onion_range_failure)); +} + inline void execute_legacy_canvas_draw_merge_plane_setup( const LegacyCanvasDrawMergePlaneSetupUniforms& uniforms, const LegacyCanvasDrawMergePlaneSetupExecution& execution) diff --git a/src/main.cpp b/src/main.cpp index 6d956d14..a45566fc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,7 +16,6 @@ #include "platform_windows/windows_vr_shell.h" #include "../resource.h" -#include #include "wacom.h" #include "abr.h" @@ -75,198 +74,6 @@ void win32_update_fps(int frames) })); } -int read_WMI_info() -{ - // see: http://win32easy.blogspot.co.uk/2011/03/wmi-in-c-query-everyting-from-your-os.html - - HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED); - if (FAILED(hRes)) - { - LOG("Unable to launch COM: %x", hRes); - return 1; - } - - if ((FAILED(hRes = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0)))) - { - LOG("Unable to initialize security: %x", hRes); - return 1; - } - - IWbemLocator* pLocator = NULL; - if (FAILED(hRes = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pLocator)))) - { - LOG("Unable to create a WbemLocator: %x", hRes); - return 1; - } - - IWbemServices* pService = NULL; - if (FAILED(hRes = pLocator->ConnectServer(BSTR(L"root\\CIMV2"), NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &pService))) - { - pLocator->Release(); - LOG("Unable to connect to \"CIMV2\": %x", hRes); - return 1; - } - - auto log_field = [](const wchar_t* section, IWbemClassObject* clsObj, const wchar_t* field) { - VARIANT vRet; - CIMTYPE pType; - VariantInit(&vRet); - if (SUCCEEDED(clsObj->Get(field, 0, &vRet, &pType, NULL))) - { - if (pType == CIM_STRING && pType != CIM_EMPTY && pType != CIM_ILLEGAL) - { - LOGW(L"%s %s: %s", section, field, vRet.bstrVal); - } - else if (pType == CIM_UINT32 && pType != CIM_EMPTY && pType != CIM_ILLEGAL) - { - LOGW(L"%s %s: %d", section, field, vRet.uintVal); - } - - VariantClear(&vRet); - } - }; - - auto get_int = [](IWbemClassObject* clsObj, const wchar_t* field) { - VARIANT vRet; - CIMTYPE pType; - VariantInit(&vRet); - int ret = 0; - if (SUCCEEDED(clsObj->Get(field, 0, &vRet, &pType, NULL))) - { - if (pType == CIM_UINT32 && pType != CIM_EMPTY && pType != CIM_ILLEGAL) - ret = vRet.uintVal; - VariantClear(&vRet); - } - return ret; - }; - - - // GET DEVICE INFO - { - IEnumWbemClassObject* pEnumerator = NULL; - if (FAILED(hRes = pService->ExecQuery(BSTR(L"WQL"), BSTR(L"SELECT * FROM Win32_ComputerSystem"), WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumerator))) - { - pLocator->Release(); - pService->Release(); - LOG("Unable to retrive desktop monitors: %x", hRes); - return 1; - } - - IWbemClassObject* clsObj = NULL; - int numElems; - while ((hRes = pEnumerator->Next(WBEM_INFINITE, 1, &clsObj, (ULONG*)&numElems)) != WBEM_S_FALSE) - { - if (FAILED(hRes)) - break; - - log_field(L"Machine", clsObj, L"Name"); - log_field(L"Machine", clsObj, L"Model"); - log_field(L"Machine", clsObj, L"Manufacturer"); - - clsObj->Release(); - } - pEnumerator->Release(); - } - - // GET OS INFO - { - IEnumWbemClassObject* pEnumerator = NULL; - if (FAILED(hRes = pService->ExecQuery(BSTR(L"WQL"), BSTR(L"SELECT * FROM Win32_OperatingSystem"), WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumerator))) - { - pLocator->Release(); - pService->Release(); - LOG("Unable to retrive desktop monitors: %x", hRes); - return 1; - } - - IWbemClassObject* clsObj = NULL; - int numElems; - while ((hRes = pEnumerator->Next(WBEM_INFINITE, 1, &clsObj, (ULONG*)&numElems)) != WBEM_S_FALSE) - { - if (FAILED(hRes)) - break; - - log_field(L"OS", clsObj, L"Name"); - log_field(L"OS", clsObj, L"Version"); - log_field(L"OS", clsObj, L"Locale"); - log_field(L"OS", clsObj, L"OSProductSuite"); - log_field(L"OS", clsObj, L"Manufacturer"); - log_field(L"OS", clsObj, L"Description"); - - clsObj->Release(); - } - pEnumerator->Release(); - } - - - pService->Release(); - pService = NULL; - if (FAILED(hRes = pLocator->ConnectServer(BSTR(L"root\\Microsoft\\Windows\\DeviceGuard"), NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &pService))) - { - pLocator->Release(); - LOG("Unable to connect to \"DeviceGuard\": %x", hRes); - return 1; - } - - // GET DEVICE GUARD - { - IEnumWbemClassObject* pEnumerator = NULL; - if (FAILED(hRes = pService->ExecQuery(BSTR(L"WQL"), BSTR(L"SELECT * FROM Win32_DeviceGuard"), WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumerator))) - { - pLocator->Release(); - pService->Release(); - LOG("Unable to retrive desktop monitors: %x", hRes); - return 1; - } - - IWbemClassObject* clsObj = NULL; - int numElems; - while ((hRes = pEnumerator->Next(WBEM_INFINITE, 1, &clsObj, (ULONG*)&numElems)) != WBEM_S_FALSE) - { - if (FAILED(hRes)) - break; - - if (get_int(clsObj, L"CodeIntegrityPolicyEnforcementStatus") > 0) - { - LOG("SANDBOX DETECTED"); - retained_state().sandboxed = true; - } - - SAFEARRAY *psaNames = NULL; - if (SUCCEEDED(clsObj->GetNames(0, WBEM_FLAG_ALWAYS | WBEM_FLAG_NONSYSTEM_ONLY, 0, &psaNames))) - { - // Get the number of properties. - long lLower, lUpper; - BSTR PropName = NULL; - SafeArrayGetLBound(psaNames, 1, &lLower); - SafeArrayGetUBound(psaNames, 1, &lUpper); - - for (long i = lLower; i <= lUpper; i++) - { - // Get this property. - SafeArrayGetElement(psaNames, &i, &PropName); - - LOGW(L"Prop: %s", PropName); - log_field(L"DeviceGuard", clsObj, PropName); - - SysFreeString(PropName); - } - - SafeArrayDestroy(psaNames); - } - - clsObj->Release(); - } - pEnumerator->Release(); - } - - - pLocator->Release(); - CoUninitialize(); - - return 0; -} - // create a reverse map from kKey to VK_XXX void init_vk_map() { @@ -329,7 +136,7 @@ int main(int argc, char** argv) pp::platform::windows::setup_exception_handler(); - read_WMI_info(); + pp::platform::windows::read_WMI_info(); App::I->create(); diff --git a/src/node_canvas.cpp b/src/node_canvas.cpp index cde6138d..46b3fc11 100644 --- a/src/node_canvas.cpp +++ b/src/node_canvas.cpp @@ -582,11 +582,6 @@ void NodeCanvas::draw() glm::mat4 proj = glm::perspective(glm::radians(m_canvas->m_cam_fov), box.z / box.w, 0.001f, 1000.f); glm::mat4 camera = glm::translate(m_canvas->m_cam_pos) * m_canvas->m_cam_rot; - m_canvas->m_mv = camera; - m_canvas->m_proj = proj; - m_canvas->m_box = box; - m_canvas->m_vp = c; - float pitch = 0; if (auto slider = root()->find("pitch-slider")) pitch = (slider->get_value() - 0.5) * glm::half_pi(); @@ -597,123 +592,81 @@ void NodeCanvas::draw() if (auto slider = root()->find("roll-slider")) roll = (slider->get_value() - 0.5) * glm::half_pi(); - // pre computed helpers - for (int plane_index = 0; plane_index < 6; plane_index++) - { - //glm::mat4 plane_camera = glm::lookAt(m_canvas->m_plane_origin[plane_index], m_canvas->m_plane_normal[plane_index], m_canvas->m_plane_tangent[plane_index]); - m_canvas->m_plane_unproject[plane_index] = glm::inverse(m_canvas->m_proj * m_canvas->m_mv * m_canvas->m_plane_transform[plane_index]); - m_canvas->m_plane_dir[plane_index] = -(m_canvas->m_plane_transform[plane_index] * glm::vec4(m_canvas->m_plane_origin[plane_index], 1)); - // face is the 2d shape of the cube plane i projected onto the window space - m_canvas->m_plane_shape[plane_index] = m_canvas->face_to_shape2D(plane_index); - } - - - if (m_density != 1.f) - { - m_rtt.bindFramebuffer(); - clear_node_canvas_color_buffer({ 1.f, 1.f, 0.f, 0.f }); - apply_node_canvas_viewport(0, 0, m_rtt.getWidth(), m_rtt.getHeight()); - } - else - { - clear_node_canvas_color_buffer({ 1.f, 1.f, 1.f, 0.f }); - apply_node_canvas_viewport(c.x + App::I->off_x, c.y + App::I->off_y, c.z, c.w); - } + pp::panopainter::prepare_legacy_node_canvas_draw_setup(*this, box, c, proj, camera); // NOTE: draw_merge has been disabled for worst performance bool draw_merged = !(m_canvas->m_current_mode == kCanvasMode::Camera); draw_merged = false; - if (draw_merged) - { - pp::panopainter::execute_legacy_canvas_draw_merge_background_setup( - { - .draw_merged = true, - }, - { - .disable_blend = [&] { - apply_node_canvas_capability(pp::renderer::gl::blend_state(), false); + pp::panopainter::execute_legacy_canvas_draw_node_canvas_shell( + m_density != 1.f, + draw_merged, + [&] { + m_rtt.bindFramebuffer(); + clear_node_canvas_color_buffer({ 1.f, 1.f, 0.f, 0.f }); + apply_node_canvas_viewport(0, 0, m_rtt.getWidth(), m_rtt.getHeight()); + }, + [&] { + clear_node_canvas_color_buffer({ 1.f, 1.f, 1.f, 0.f }); + apply_node_canvas_viewport(c.x + App::I->off_x, c.y + App::I->off_y, c.z, c.w); + }, + [&] { + pp::panopainter::execute_legacy_canvas_draw_merged_pass( + *this, + proj, + camera, + [&](auto state, bool enabled) { + apply_node_canvas_capability(state, enabled); }, - .draw_checkerboard_plane = pp::panopainter::make_legacy_canvas_draw_merge_background_checkerboard_plane( - proj, - camera, - m_canvas->m_layers.size() + 500.f, - m_canvas->m_plane_transform, - [&] { - m_face_plane.draw_fill(); - }), - }); + [](int unit) { + set_active_texture_unit(unit); + }, + [&] { + m_face_plane.draw_fill(); + }); + }, + [&] { + const auto blend_gate = node_canvas_blend_gate_plan( + m_cache_rtt.getWidth(), + m_cache_rtt.getHeight(), + m_canvas->m_layers, + m_canvas->m_current_stroke ? m_canvas->m_current_stroke->m_brush.get() : nullptr); + const bool use_blend = blend_gate.shader_blend; + const bool copy_blend_destination = use_blend && !blend_gate.reads_destination_color; + const auto layer_orientation = glm::eulerAngleYXZ(yaw, pitch, roll); - const auto draw_merged_texture_plane = pp::panopainter::make_legacy_canvas_draw_merge_layer_texture_draw( - &m_canvas->m_layers_merge, - &m_sampler, - &m_face_plane, - set_active_texture_unit, - proj, - camera, - m_canvas->m_plane_transform); - - for (int plane_index = 0; plane_index < 6; plane_index++) - { - draw_merged_texture_plane(plane_index); - } - } - else - { - const auto blend_gate = node_canvas_blend_gate_plan( - m_cache_rtt.getWidth(), - m_cache_rtt.getHeight(), - m_canvas->m_layers, - m_canvas->m_current_stroke ? m_canvas->m_current_stroke->m_brush.get() : nullptr); - const bool use_blend = blend_gate.shader_blend; - const bool copy_blend_destination = use_blend && !blend_gate.reads_destination_color; - const auto layer_orientation = glm::eulerAngleYXZ(yaw, pitch, roll); - - const auto& b = m_canvas->m_current_stroke->m_brush; - pp::panopainter::execute_legacy_canvas_draw_unmerged_node_canvas_pass( - *this, - use_blend, - proj, - camera, - layer_orientation, - c, - [&](int x, int y, int width, int height) { - apply_node_canvas_viewport(x, y, width, height); - }, - [&](auto state, bool enabled) { - apply_node_canvas_capability(state, enabled); - }, - [&] { - m_face_plane.draw_fill(); - }, - [&] { - m_sampler.bind(0); - set_active_texture_unit(0); - }, - [&](size_t layer_index, int plane_index, const glm::mat4& plane_mvp_z) { - return make_node_canvas_layer_path_execution( - *this, - layer_index, - plane_index, - plane_mvp_z, - b.get(), - copy_blend_destination, - m_canvas->m_cam_fov < 20.f); - }, - [&] { - return pp::panopainter::make_legacy_canvas_draw_merge_cache_to_screen_checkerboard_plane( - proj, - camera, - m_canvas->m_layers.size() + 500.f, - m_canvas->m_plane_transform, - [&] { - m_face_plane.draw_fill(); - }); - }, - [&](const char* message) { - LOG("NodeCanvas onion frame range failed: %s", message); - }); - } + pp::panopainter::execute_legacy_canvas_draw_node_canvas_unmerged_pass( + *this, + use_blend, + copy_blend_destination, + proj, + camera, + layer_orientation, + c, + [&](int x, int y, int width, int height) { + apply_node_canvas_viewport(x, y, width, height); + }, + [&](auto state, bool enabled) { + apply_node_canvas_capability(state, enabled); + }, + [&] { + m_sampler.bind(0); + set_active_texture_unit(0); + }, + [&](size_t layer_index, int plane_index, const glm::mat4& plane_mvp_z, const Brush* brush, bool copy_blend_destination, bool use_nearest_sampler) { + return make_node_canvas_layer_path_execution( + *this, + layer_index, + plane_index, + plane_mvp_z, + brush, + copy_blend_destination, + use_nearest_sampler); + }, + [&](const char* message) { + LOG("NodeCanvas onion frame range failed: %s", message); + }); + }); execute_node_canvas_draw_merge_tail(*this, ortho_proj, proj, camera, c); diff --git a/src/platform_windows/windows_bootstrap_helpers.cpp b/src/platform_windows/windows_bootstrap_helpers.cpp index 273a0bec..da78f921 100644 --- a/src/platform_windows/windows_bootstrap_helpers.cpp +++ b/src/platform_windows/windows_bootstrap_helpers.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -162,6 +163,198 @@ void setup_exception_handler() BT_SetTerminate(); } +int read_WMI_info() +{ + // see: http://win32easy.blogspot.co.uk/2011/03/wmi-in-c-query-everyting-from-your-os.html + + HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED); + if (FAILED(hRes)) + { + LOG("Unable to launch COM: %x", hRes); + return 1; + } + + if ((FAILED(hRes = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0)))) + { + LOG("Unable to initialize security: %x", hRes); + return 1; + } + + IWbemLocator* pLocator = NULL; + if (FAILED(hRes = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pLocator)))) + { + LOG("Unable to create a WbemLocator: %x", hRes); + return 1; + } + + IWbemServices* pService = NULL; + if (FAILED(hRes = pLocator->ConnectServer(BSTR(L"root\\CIMV2"), NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &pService))) + { + pLocator->Release(); + LOG("Unable to connect to \"CIMV2\": %x", hRes); + return 1; + } + + auto log_field = [](const wchar_t* section, IWbemClassObject* clsObj, const wchar_t* field) { + VARIANT vRet; + CIMTYPE pType; + VariantInit(&vRet); + if (SUCCEEDED(clsObj->Get(field, 0, &vRet, &pType, NULL))) + { + if (pType == CIM_STRING && pType != CIM_EMPTY && pType != CIM_ILLEGAL) + { + LOGW(L"%s %s: %s", section, field, vRet.bstrVal); + } + else if (pType == CIM_UINT32 && pType != CIM_EMPTY && pType != CIM_ILLEGAL) + { + LOGW(L"%s %s: %d", section, field, vRet.uintVal); + } + + VariantClear(&vRet); + } + }; + + auto get_int = [](IWbemClassObject* clsObj, const wchar_t* field) { + VARIANT vRet; + CIMTYPE pType; + VariantInit(&vRet); + int ret = 0; + if (SUCCEEDED(clsObj->Get(field, 0, &vRet, &pType, NULL))) + { + if (pType == CIM_UINT32 && pType != CIM_EMPTY && pType != CIM_ILLEGAL) + ret = vRet.uintVal; + VariantClear(&vRet); + } + return ret; + }; + + + // GET DEVICE INFO + { + IEnumWbemClassObject* pEnumerator = NULL; + if (FAILED(hRes = pService->ExecQuery(BSTR(L"WQL"), BSTR(L"SELECT * FROM Win32_ComputerSystem"), WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumerator))) + { + pLocator->Release(); + pService->Release(); + LOG("Unable to retrive desktop monitors: %x", hRes); + return 1; + } + + IWbemClassObject* clsObj = NULL; + int numElems; + while ((hRes = pEnumerator->Next(WBEM_INFINITE, 1, &clsObj, (ULONG*)&numElems)) != WBEM_S_FALSE) + { + if (FAILED(hRes)) + break; + + log_field(L"Machine", clsObj, L"Name"); + log_field(L"Machine", clsObj, L"Model"); + log_field(L"Machine", clsObj, L"Manufacturer"); + + clsObj->Release(); + } + pEnumerator->Release(); + } + + // GET OS INFO + { + IEnumWbemClassObject* pEnumerator = NULL; + if (FAILED(hRes = pService->ExecQuery(BSTR(L"WQL"), BSTR(L"SELECT * FROM Win32_OperatingSystem"), WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumerator))) + { + pLocator->Release(); + pService->Release(); + LOG("Unable to retrive desktop monitors: %x", hRes); + return 1; + } + + IWbemClassObject* clsObj = NULL; + int numElems; + while ((hRes = pEnumerator->Next(WBEM_INFINITE, 1, &clsObj, (ULONG*)&numElems)) != WBEM_S_FALSE) + { + if (FAILED(hRes)) + break; + + log_field(L"OS", clsObj, L"Name"); + log_field(L"OS", clsObj, L"Version"); + log_field(L"OS", clsObj, L"Locale"); + log_field(L"OS", clsObj, L"OSProductSuite"); + log_field(L"OS", clsObj, L"Manufacturer"); + log_field(L"OS", clsObj, L"Description"); + + clsObj->Release(); + } + pEnumerator->Release(); + } + + + pService->Release(); + pService = NULL; + if (FAILED(hRes = pLocator->ConnectServer(BSTR(L"root\\Microsoft\\Windows\\DeviceGuard"), NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &pService))) + { + pLocator->Release(); + LOG("Unable to connect to \"DeviceGuard\": %x", hRes); + return 1; + } + + // GET DEVICE GUARD + { + IEnumWbemClassObject* pEnumerator = NULL; + if (FAILED(hRes = pService->ExecQuery(BSTR(L"WQL"), BSTR(L"SELECT * FROM Win32_DeviceGuard"), WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumerator))) + { + pLocator->Release(); + pService->Release(); + LOG("Unable to retrive desktop monitors: %x", hRes); + return 1; + } + + IWbemClassObject* clsObj = NULL; + int numElems; + while ((hRes = pEnumerator->Next(WBEM_INFINITE, 1, &clsObj, (ULONG*)&numElems)) != WBEM_S_FALSE) + { + if (FAILED(hRes)) + break; + + if (get_int(clsObj, L"CodeIntegrityPolicyEnforcementStatus") > 0) + { + LOG("SANDBOX DETECTED"); + retained_state().sandboxed = true; + } + + SAFEARRAY *psaNames = NULL; + if (SUCCEEDED(clsObj->GetNames(0, WBEM_FLAG_ALWAYS | WBEM_FLAG_NONSYSTEM_ONLY, 0, &psaNames))) + { + // Get the number of properties. + long lLower, lUpper; + BSTR PropName = NULL; + SafeArrayGetLBound(psaNames, 1, &lLower); + SafeArrayGetUBound(psaNames, 1, &lUpper); + + for (long i = lLower; i <= lUpper; i++) + { + // Get this property. + SafeArrayGetElement(psaNames, &i, &PropName); + + LOGW(L"Prop: %s", PropName); + log_field(L"DeviceGuard", clsObj, PropName); + + SysFreeString(PropName); + } + + SafeArrayDestroy(psaNames); + } + + clsObj->Release(); + } + pEnumerator->Release(); + } + + + pLocator->Release(); + CoUninitialize(); + + return 0; +} + MainWindowStartupState initialize_main_window_startup_state() { auto startup = MainWindowStartupState {}; diff --git a/src/platform_windows/windows_bootstrap_helpers.h b/src/platform_windows/windows_bootstrap_helpers.h index 6eefa156..3b50962b 100644 --- a/src/platform_windows/windows_bootstrap_helpers.h +++ b/src/platform_windows/windows_bootstrap_helpers.h @@ -20,6 +20,7 @@ void init_shcore_API(); std::string GetLastErrorAsString(); void _pre_call_callback(const char* name, void* funcptr, int len_args, ...); void _post_call_callback(const char* name, void* funcptr, int len_args, ...); +int read_WMI_info(); struct MainWindowStartupState {