Skip to content

Commit

Permalink
nodes: initial resurrection of dual monitor/secondary window for crob…
Browse files Browse the repository at this point in the history
…by49

secondary window doesn't yet have any input/mouse interaction, also resizing probably doesn't work etc.
  • Loading branch information
hanatos committed Sep 15, 2024
1 parent 1deed55 commit 1464089
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 32 deletions.
79 changes: 68 additions & 11 deletions src/gui/gui.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ style_to_state()
}

static inline void
dt_gui_init_win(dt_gui_win_t *win)
dt_gui_win_init(dt_gui_win_t *win)
{
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
Expand All @@ -49,7 +49,7 @@ dt_gui_init_win(dt_gui_win_t *win)
}

static inline int
dt_gui_init_win_vk(dt_gui_win_t *win)
dt_gui_win_init_vk(dt_gui_win_t *win)
{
/* create surface */
if(glfwCreateWindowSurface(qvk.instance, win->window, NULL, &win->surface))
Expand Down Expand Up @@ -140,7 +140,7 @@ int dt_gui_init()
float rel_fontsize = 2.0f / 55.0f * dpi_scale;
vkdt.style.panel_width_frac = 0.2f;
vkdt.style.border_frac = rel_fontsize * 1.05f; // large enough to fit 2x fontsize heading
dt_gui_init_win(&vkdt.win);
dt_gui_win_init(&vkdt.win);

// be verbose about monitor names so we can colour manage them:
int monitors_cnt;
Expand Down Expand Up @@ -180,7 +180,7 @@ int dt_gui_init()
return 1;
}

dt_gui_init_win_vk(&vkdt.win);
dt_gui_win_init_vk(&vkdt.win);

// joystick detection:
vkdt.wstate.have_joystick = glfwJoystickPresent(GLFW_JOYSTICK_1);
Expand Down Expand Up @@ -211,9 +211,17 @@ static inline VkResult
dt_gui_destroy_swapchain(dt_gui_win_t *win)
{
for(int i = 0; i < win->num_swap_chain_images; i++)
vkDestroyImageView(qvk.device, win->swap_chain_image_views[i], NULL);
{
if(win->swap_chain_image_views[i]) vkDestroyImageView (qvk.device, win->swap_chain_image_views[i], 0);
if(win->framebuffer[i]) vkDestroyFramebuffer(qvk.device, win->framebuffer[i], 0);
if(win->render_pass) vkDestroyRenderPass (qvk.device, win->render_pass, 0);
win->swap_chain_image_views[i] = 0;
win->framebuffer[i] = 0;
win->render_pass = 0;
}

vkDestroySwapchainKHR(qvk.device, win->swap_chain, NULL);
win->swap_chain = 0;
return VK_SUCCESS;
}

Expand Down Expand Up @@ -438,7 +446,7 @@ dt_gui_recreate_swapchain(dt_gui_win_t *win)
}

static inline void
dt_gui_cleanup_win(dt_gui_win_t *win)
dt_gui_win_cleanup(dt_gui_win_t *win)
{
for(int i=0;i<win->num_swap_chain_images;i++)
{
Expand All @@ -448,26 +456,37 @@ dt_gui_cleanup_win(dt_gui_win_t *win)
vkDestroySemaphore(qvk.device, win->sem_render_complete[i], 0);
vkDestroyFence(qvk.device, win->fence[i], 0);
vkDestroyFramebuffer(qvk.device, win->framebuffer[i], 0);
win->command_buffer[i] = 0;
win->command_pool[i] = 0;
win->sem_image_acquired[i] = 0;
win->sem_render_complete[i] = 0;
win->fence[i] = 0;
win->framebuffer[i] = 0;
}
if(win->render_pass)
vkDestroyRenderPass(qvk.device, win->render_pass, 0);
win->render_pass = 0;
vkDestroyDescriptorPool(qvk.device, win->descriptor_pool, 0);
win->descriptor_pool = 0;

if(win->window) dt_gui_destroy_swapchain(win);
if(win->surface) vkDestroySurfaceKHR(qvk.instance, win->surface, NULL);
glfwDestroyWindow(win->window);
win->window = 0;
win->surface = 0;
}

void dt_gui_cleanup()
{
dt_gui_win1_close();
dt_gui_cleanup_nk();
char configfile[512];
if(snprintf(configfile, sizeof(configfile), "%s/config.rc", dt_pipe.homedir) < 512)
dt_rc_write(&vkdt.rc, configfile);
dt_rc_cleanup(&vkdt.rc);
dt_graph_cleanup(&vkdt.graph_dev);

dt_gui_cleanup_win(&vkdt.win);
dt_gui_win_cleanup(&vkdt.win);

qvk_cleanup();
glfwTerminate();
Expand Down Expand Up @@ -553,16 +572,25 @@ dt_gui_render_win_end(dt_gui_win_t *win)

VkResult dt_gui_render()
{
QVKR(dt_gui_render_win_beg(&vkdt.win));

// potentially set off commands for both ctx/win
dt_gui_render_frame_nk();

// TODO: pass win
const int have_win1 = vkdt.win1.window != 0;
QVKR(dt_gui_render_win_beg(&vkdt.win));
if(have_win1)
QVKR(dt_gui_render_win_beg(&vkdt.win1));

int num = vkdt.win.num_swap_chain_images;
if(have_win1) num += vkdt.win1.num_swap_chain_images;
nk_glfw3_create_cmd(&vkdt.ctx, vkdt.win.command_buffer[vkdt.win.frame_index],
NK_ANTI_ALIASING_ON, vkdt.win.frame_index, vkdt.win.num_swap_chain_images);
NK_ANTI_ALIASING_ON, vkdt.win.frame_index, num);
if(have_win1)
nk_glfw3_create_cmd(&vkdt.ctx1, vkdt.win1.command_buffer[vkdt.win1.frame_index],
NK_ANTI_ALIASING_ON, vkdt.win.num_swap_chain_images + vkdt.win1.frame_index, num);

QVKR(dt_gui_render_win_end(&vkdt.win));
if(have_win1)
QVKR(dt_gui_render_win_end(&vkdt.win1));
return VK_SUCCESS;
}

Expand All @@ -586,6 +614,8 @@ dt_gui_present_win(dt_gui_win_t *win)

VkResult dt_gui_present()
{
if(vkdt.win1.window)
QVKR(dt_gui_present_win(&vkdt.win1));
return dt_gui_present_win(&vkdt.win);
}

Expand Down Expand Up @@ -790,3 +820,30 @@ void dt_gui_notification(const char *msg, ...)
threads_mutex_unlock(&vkdt.wstate.notification_mutex);
}

void dt_gui_win1_close()
{
if(!vkdt.win1.window) return;
QVKL(&qvk.queue[qvk.qid[s_queue_graphics]].mutex, vkQueueWaitIdle(qvk.queue[qvk.qid[s_queue_graphics]].queue));
dt_gui_win_cleanup(&vkdt.win1);
nk_free(&vkdt.ctx1);
}

void dt_gui_win1_open()
{
if(vkdt.win1.window) dt_gui_win1_close();
dt_gui_win_init(&vkdt.win1);
dt_gui_win_init_vk(&vkdt.win1);
nk_init_default(&vkdt.ctx1, 0);
#if 0 // this is for event handling and will break if we call it on win1
nk_glfw3_init(
&vkdt.ctx1,
vkdt.win1.render_pass,
vkdt.win1.window,
qvk.device, qvk.physical_device,
vkdt.win1.num_swap_chain_images * 2560*1024,
vkdt.win1.num_swap_chain_images * 640*1024);
#endif
nk_style_default(&vkdt.ctx1);
nk_style_from_table(&vkdt.ctx1, vkdt.style.colour);
nk_style_set_font(&vkdt.ctx1, &dt_gui_get_font(0)->handle);
}
6 changes: 6 additions & 0 deletions src/gui/gui.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,9 @@ void dt_gui_grab_mouse();

// ungrab the mouse, pass it on to nuklear again
void dt_gui_ungrab_mouse();

// open secondary window for dual screen use
void dt_gui_win1_open();

// close secondary window
void dt_gui_win1_close();
6 changes: 0 additions & 6 deletions src/gui/render.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,11 @@ void dt_gui_init_fonts()
nk_style_set_font(&vkdt.ctx, &g_font[0]->handle);
}


int dt_gui_init_nk()
{
vkdt.wstate.lod = dt_rc_get_int(&vkdt.rc, "gui/lod", 1); // set finest lod by default

nk_init_default(&vkdt.ctx, 0);
// nk_init_default(&vkdt.ctx1, 0); // TODO secondary screen
nk_glfw3_init(
&vkdt.ctx,
vkdt.win.render_pass,
Expand All @@ -148,8 +146,6 @@ int dt_gui_init_nk()
vkdt.win.num_swap_chain_images * 2560*1024,
vkdt.win.num_swap_chain_images * 640*1024);

// XXX setup multi viewport for dual screen! (requires a second ctx and manual handling of the second viewport/command buffer)

read_style_colours(&vkdt.ctx);

char tmp[PATH_MAX+100] = {0};
Expand Down Expand Up @@ -276,8 +272,6 @@ void dt_gui_render_frame_nk()
}
threads_mutex_unlock(&vkdt.wstate.notification_mutex);

// TODO: now render second screen context, if any (this will only be a full res image widget, we could put the code here)

// nuklear requires the input, when modifying a text edit etc:
vkdt.wstate.nk_active = vkdt.wstate.nk_active_next;
vkdt.wstate.nk_active_next = 0;
Expand Down
47 changes: 32 additions & 15 deletions src/gui/render_nodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ typedef struct gui_nodes_t
{
int do_layout; // do initial auto layout
int node_hovered_link;
int dual_monitor;
dt_node_editor_t nedit;
}
gui_nodes_t;
Expand Down Expand Up @@ -67,18 +66,37 @@ void render_nodes_right_panel()
dt_node_t *out = dt_graph_get_display(&vkdt.graph_dev, dsp[d]);
if(out && vkdt.graph_res == VK_SUCCESS)
{
// int popout = dsp[d] == dt_token("main") && nodes.dual_monitor;
const int popout = (dsp[d] == dt_token("main")) && vkdt.win1.window;
char title[20] = {0};
snprintf(title, sizeof(title), "nodes %" PRItkn, dt_token_str(dsp[d]));
// if(popout) // TODO use vkdt.ctx2 and decorate with some window around it
struct nk_context *ctx = &vkdt.ctx;
int wd = vkdt.state.panel_wd;
int ht = wd * out->connector[0].roi.full_ht / (float)out->connector[0].roi.full_wd; // image aspect
nk_layout_row_dynamic(&vkdt.ctx, ht, 1);
if(dsp[d] == dt_token("main"))
dt_image(&vkdt.ctx, &vkdt.wstate.img_widget, out, 1, 1);
else
dt_image(&vkdt.ctx, imgw+d, out, 1, 0);
// if(popout) // TODO: nk_end and stuff?
int visible = 1;
if(popout)
{
ctx = &vkdt.ctx1;
struct nk_rect bounds = {0, 0, vkdt.win1.width, vkdt.win1.height};
wd = vkdt.win1.width;
nk_style_push_style_item(ctx, &ctx->style.window.fixed_background, nk_style_item_color(vkdt.style.colour[NK_COLOR_DT_BACKGROUND]));
int disabled = 1; // XXX try this later
if(!nk_begin(ctx, "vkdt secondary", bounds, NK_WINDOW_NO_SCROLLBAR | (disabled ? NK_WINDOW_NO_INPUT : 0)))
visible = 0;
}
if(visible)
{
int ht = wd * out->connector[0].roi.full_ht / (float)out->connector[0].roi.full_wd; // image aspect
nk_layout_row_dynamic(ctx, ht, 1);
if(dsp[d] == dt_token("main"))
dt_image(ctx, &vkdt.wstate.img_widget, out, 1, popout ? 0 : 1);
else
dt_image(ctx, imgw+d, out, 1, 0);
}
if(popout)
{
// NK_UPDATE_ACTIVE; ??
nk_end(ctx);
nk_style_pop_style_item(ctx);
}
}
}
// expanders for selection and individual nodes:
Expand All @@ -94,10 +112,10 @@ void render_nodes_right_panel()
nk_style_push_flags(&vkdt.ctx, &vkdt.ctx.style.button.text_alignment, NK_TEXT_LEFT);
if(nk_button_label(ctx, "hotkeys"))
dt_gui_edit_hotkeys();
if(nodes.dual_monitor && nk_button_label(ctx, "single monitor"))
nodes.dual_monitor = 0;
else if(!nodes.dual_monitor && nk_button_label(ctx, "dual monitor"))
nodes.dual_monitor = 1;
if(vkdt.win1.window && nk_button_label(ctx, "single monitor"))
dt_gui_win1_close();
else if(!vkdt.win1.window && nk_button_label(ctx, "dual monitor"))
dt_gui_win1_open();
nk_style_pop_flags(ctx);
nk_tree_pop(ctx);
}
Expand Down Expand Up @@ -230,7 +248,6 @@ void render_nodes_cleanup()

int nodes_enter()
{
nodes.dual_monitor = 0; // XXX TODO: get from rc and write on leave
nodes.node_hovered_link = -1;
nodes.do_layout = 1; // maybe overwrite uninited node positions
// make sure we process once:
Expand Down

0 comments on commit 1464089

Please sign in to comment.