Commit 93bc7268 authored by Christoph Haag's avatar Christoph Haag

WIP: xrd-render-lock: improve locking

Most changes inside xrdesktop are caused by user input. Instead of littering everything
fine granular with locking, rather lock around gxr_action_sets_poll().
Since g_timeout callbacks run on the main thread, everything caused by user input is locked.

Remaining locks are necessary around:
* Adding and removing windows (locking is contained in XrdWindowManager)
* Callbacks on a timer, e.g. pointer tip animation

We use a recursive mutex, because adding windows can have two sources:
1. Newly created window is added by window manager integration
2. Opening the xrd button menu, caused by input which is already locked (on the same thread)
parent c050cabc
Pipeline #119399 passed with stage
in 1 minute and 53 seconds
......@@ -131,12 +131,9 @@ _desktop_window_to_texture (Example *self,
GulkanClient *gc = xrd_client_get_gulkan (self->client);
VkImageLayout layout = xrd_client_get_upload_layout (self->client);
/* texture uploads use gulkan's shared CommandPool */
xrd_render_lock ();
GulkanTexture *tex =
gulkan_texture_new_from_pixbuf (gc, desktop_window->pixbuf,
VK_FORMAT_R8G8B8A8_UNORM, layout, TRUE);
xrd_render_unlock ();
return tex;
}
......@@ -571,11 +568,12 @@ _reupload_thread (gpointer data)
else
pixbuf = self->bw_window_pixbuf;
xrd_render_lock ();
/* TODO: sync on GPU
* This texture upload should be locked but it takes too long */
GulkanTexture *tex =
gulkan_texture_new_from_pixbuf (gc, pixbuf,
VK_FORMAT_R8G8B8A8_UNORM, layout, TRUE);
xrd_render_lock ();
xrd_window_set_and_submit_texture (xrd_window, tex);
xrd_render_unlock ();
......
......@@ -155,11 +155,8 @@ _render_thread (gpointer _self)
while (!self->shutdown_render_thread)
{
xrd_render_lock ();
xrd_scene_client_render (self);
xrd_render_unlock ();
g_usleep (10);
g_thread_yield ();
}
g_debug ("Stopped XrdSceneClient render thread, bye.\n");
......@@ -438,7 +435,10 @@ xrd_scene_client_render (XrdSceneClient *self)
}
XrdSceneRenderer *renderer = xrd_scene_renderer_get_instance ();
xrd_render_lock ();
xrd_scene_renderer_draw (renderer);
xrd_render_unlock ();
GxrPose poses[GXR_DEVICE_INDEX_MAX];
gxr_context_end_frame (context, poses);
......
......@@ -197,7 +197,6 @@ _submit_cairo_surface (XrdWindow *button,
VkImageLayout upload_layout,
cairo_surface_t* surface)
{
xrd_render_lock ();
GulkanTexture *texture =
gulkan_texture_new_from_cairo_surface (client, surface,
VK_FORMAT_R8G8B8A8_UNORM,
......@@ -211,8 +210,6 @@ _submit_cairo_surface (XrdWindow *button,
}
xrd_window_set_and_submit_texture (button, texture);
xrd_render_unlock ();
}
void
......
......@@ -254,6 +254,7 @@ xrd_client_add_window (XrdClient *self,
XrdWindowManager *manager = xrd_client_get_manager (self);
xrd_window_manager_add_window (manager, window, flags);
XrdClientPrivate *priv = xrd_client_get_instance_private (self);
if (priv->pinned_only &&
!(flags & XRD_WINDOW_BUTTON) &&
......@@ -378,13 +379,11 @@ xrd_client_add_button (XrdClient *self,
XrdWindowManager *manager = xrd_client_get_manager (self);
xrd_render_lock ();
xrd_window_manager_add_window (manager,
button,
XRD_WINDOW_HOVERABLE |
XRD_WINDOW_DESTROY_WITH_PARENT |
XRD_WINDOW_BUTTON);
xrd_render_lock ();
g_signal_connect (button, "grab-start-event",
(GCallback) press_callback, press_callback_data);
......@@ -752,6 +751,8 @@ xrd_client_poll_input_events (XrdClient *self)
gboolean poll_synth = _is_hovering (self) && !_is_grabbing (self);
uint32_t count = poll_synth ? 2 : 1;
/* This lock includes all callbacks caused by input events */
xrd_render_lock ();
if (!gxr_action_sets_poll (priv->action_sets, count))
{
g_printerr ("Error polling actions\n");
......@@ -760,6 +761,7 @@ xrd_client_poll_input_events (XrdClient *self)
}
xrd_window_manager_poll_window_events (priv->manager, priv->context);
xrd_render_unlock ();
priv->last_poll_timestamp = g_get_monotonic_time ();
return TRUE;
......
......@@ -32,6 +32,7 @@ void
xrd_desktop_cursor_submit_texture (XrdDesktopCursor *self)
{
XrdDesktopCursorInterface* iface = XRD_DESKTOP_CURSOR_GET_IFACE (self);
/* TODO: sync on GPU */
xrd_render_lock ();
iface->submit_texture (self);
xrd_render_unlock ();
......@@ -49,6 +50,7 @@ xrd_desktop_cursor_set_and_submit_texture (XrdDesktopCursor *self,
GulkanTexture *texture)
{
XrdDesktopCursorInterface* iface = XRD_DESKTOP_CURSOR_GET_IFACE (self);
/* TODO: sync on GPU */
xrd_render_lock ();
iface->set_and_submit_texture (self, texture);
xrd_render_unlock ();
......
......@@ -375,6 +375,7 @@ _animate_cb (gpointer _animation)
GdkPixbuf* pixbuf = xrd_pointer_tip_render (tip, animation->progress);
/* TODO: sync on GPU */
xrd_render_lock ();
gulkan_texture_upload_pixbuf (texture, pixbuf, data->upload_layout);
xrd_pointer_tip_submit_texture (tip);
......
......@@ -7,7 +7,7 @@
#include "xrd-render-lock.h"
static GMutex render_mutex;
static GRecMutex render_mutex;
static volatile gint initialized = 0;
void
......@@ -25,14 +25,19 @@ xrd_render_lock_destroy ()
void
xrd_render_lock ()
{
if (g_atomic_int_get (&initialized) == 1)
g_mutex_lock (&render_mutex);
{
//g_print ("Lock!\n");
g_rec_mutex_lock (&render_mutex);
}
}
void
xrd_render_unlock ()
{
if (g_atomic_int_get (&initialized) == 1)
g_mutex_unlock (&render_mutex);
{
//g_print ("Unlock!\n");
g_rec_mutex_unlock (&render_mutex);
}
}
......@@ -14,6 +14,7 @@
#include "graphene-ext.h"
#include "xrd-controller.h"
#include "xrd-render-lock.h"
#ifndef M_PI
#define M_PI (3.14159265358979323846)
......@@ -119,6 +120,8 @@ _interpolate_cb (gpointer _transition)
&transition->to,
curve,
&interpolated);
xrd_render_lock ();
xrd_window_set_transformation (window, &interpolated);
float interpolated_scaling =
......@@ -145,9 +148,12 @@ _interpolate_cb (gpointer _transition)
g_object_unref (transition->window);
g_free (transition);
xrd_render_unlock ();
return FALSE;
}
xrd_render_unlock ();
return TRUE;
}
......@@ -352,6 +358,7 @@ xrd_window_manager_add_window (XrdWindowManager *self,
XrdWindow *window,
XrdWindowFlags flags)
{
xrd_render_lock ();
/* any window must be either in all_windows or buttons */
if (flags & XRD_WINDOW_BUTTON)
{
......@@ -382,6 +389,7 @@ xrd_window_manager_add_window (XrdWindowManager *self,
/* keep the window referenced as long as the window manages this window */
g_object_ref (window);
xrd_render_unlock ();
}
void
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment