Merge pull request #3755 from matt335672/gfx_resize

resizing: Simplify GFX resizing
This commit is contained in:
matt335672
2026-04-06 12:46:46 +01:00
committed by GitHub
4 changed files with 76 additions and 125 deletions
-3
View File
@@ -493,9 +493,6 @@ struct display_control_monitor_layout_data
enum display_resize_state state; enum display_resize_state state;
unsigned int last_state_update_timestamp; unsigned int last_state_update_timestamp;
unsigned int start_time; unsigned int start_time;
/// This flag is set if the state machine needs to
/// shutdown/startup EGFX
int using_egfx;
}; };
enum resize_queue_source enum resize_queue_source
-15
View File
@@ -936,22 +936,7 @@ xrdp_egfx_open_response(struct xrdp_process *id, int chan_id,
static int static int
xrdp_egfx_close_response(struct xrdp_process *id, int chan_id) xrdp_egfx_close_response(struct xrdp_process *id, int chan_id)
{ {
struct xrdp_mm *mm;
LOG(LOG_LEVEL_TRACE, "xrdp_egfx_close_response:"); LOG(LOG_LEVEL_TRACE, "xrdp_egfx_close_response:");
mm = id->wm->mm;
if (mm->resize_queue == 0 || mm->resize_queue->count <= 0)
{
return 0;
}
if (mm->resize_data != NULL
&& mm->resize_data->state == WMRZ_EGFX_CONN_CLOSING)
{
LOG(LOG_LEVEL_DEBUG, "xrdp_egfx_close_response: egfx deleted.");
advance_resize_state_machine(mm, WMRZ_EGFX_CONN_CLOSED);
}
return 0; return 0;
} }
+74 -91
View File
@@ -1142,6 +1142,29 @@ xrdp_mm_egfx_create_surfaces(struct xrdp_mm *self)
return 0; return 0;
} }
/******************************************************************************/
static int
xrdp_mm_egfx_delete_surfaces(struct xrdp_mm *self)
{
int index;
int count = self->wm->client_info->display_sizes.monitorCount;
LOG_DEVEL(LOG_LEVEL_INFO, "xrdp_mm_egfx_delete_surfaces: "
"monitor count %d", count);
if (count < 1)
{
xrdp_egfx_send_delete_surface(self->egfx, self->egfx->surface_id);
}
else
{
for (index = 0; index < count; index++)
{
xrdp_egfx_send_delete_surface(self->egfx, index);
}
}
return 0;
}
/******************************************************************************/ /******************************************************************************/
static int static int
xrdp_mm_egfx_caps_advertise(void *user, int caps_count, xrdp_mm_egfx_caps_advertise(void *user, int caps_count,
@@ -1276,11 +1299,6 @@ xrdp_mm_egfx_caps_advertise(void *user, int caps_count,
self->encoder = xrdp_encoder_create(self); self->encoder = xrdp_encoder_create(self);
xrdp_mm_egfx_invalidate_wm_screen(self); xrdp_mm_egfx_invalidate_wm_screen(self);
if (self->resize_data != NULL
&& self->resize_data->state == WMRZ_EGFX_INITALIZING)
{
advance_resize_state_machine(self, WMRZ_EGFX_INITIALIZED);
}
LOG(LOG_LEVEL_INFO, "xrdp_mm_egfx_caps_advertise: egfx created."); LOG(LOG_LEVEL_INFO, "xrdp_mm_egfx_caps_advertise: egfx created.");
if (self->gfx_delay_autologin) if (self->gfx_delay_autologin)
{ {
@@ -1616,14 +1634,11 @@ process_display_control_monitor_layout_data(struct xrdp_wm *wm)
int error = 0; int error = 0;
struct xrdp_mm *mm; struct xrdp_mm *mm;
struct xrdp_mod *module; struct xrdp_mod *module;
struct xrdp_rdp *rdp;
struct xrdp_sec *sec;
struct xrdp_channel *chan;
int in_progress; int in_progress;
LOG_DEVEL(LOG_LEVEL_TRACE, "process_display_control_monitor_layout_data:"); LOG_DEVEL(LOG_LEVEL_TRACE, "process_display_control_monitor_layout_data:");
if (wm == NULL) if (wm == NULL || wm->session == NULL || wm->session->rdp == NULL)
{ {
return 1; return 1;
} }
@@ -1652,8 +1667,7 @@ process_display_control_monitor_layout_data(struct xrdp_wm *wm)
{ {
case WMRZ_ENCODER_DELETE: case WMRZ_ENCODER_DELETE:
// Stop any output from the module // Stop any output from the module
rdp = wm->session->rdp; xrdp_rdp_suppress_output(wm->session->rdp,
xrdp_rdp_suppress_output(rdp,
1, XSO_REASON_DYNAMIC_RESIZE, 1, XSO_REASON_DYNAMIC_RESIZE,
0, 0, 0, 0); 0, 0, 0, 0);
// Disable the encoder until the resize is complete. // Disable the encoder until the resize is complete.
@@ -1662,58 +1676,35 @@ process_display_control_monitor_layout_data(struct xrdp_wm *wm)
xrdp_encoder_delete(mm->encoder); xrdp_encoder_delete(mm->encoder);
mm->encoder = NULL; mm->encoder = NULL;
} }
if (mm->resize_data->using_egfx == 0) if (!mm->egfx_up)
{ {
advance_resize_state_machine(mm, WMRZ_SERVER_MONITOR_RESIZE); advance_resize_state_machine(mm, WMRZ_SERVER_MONITOR_RESIZE);
} }
else else
{ {
advance_resize_state_machine(mm, WMRZ_EGFX_DELETE_SURFACE); advance_resize_state_machine(mm, WMRZ_EGFX_RESET_GRAPHICS);
} }
break; break;
case WMRZ_EGFX_DELETE_SURFACE:
if (error == 0 && module != 0)
{
xrdp_egfx_shutdown_delete_surface(mm->egfx);
}
advance_resize_state_machine(mm, WMRZ_EGFX_CONN_CLOSE);
break;
case WMRZ_EGFX_CONN_CLOSE:
if (error == 0 && module != 0)
{
xrdp_egfx_shutdown_close_connection(wm->mm->egfx);
mm->egfx_up = 0;
}
advance_resize_state_machine(mm, WMRZ_EGFX_CONN_CLOSING);
break;
// Also processed in xrdp_egfx_close_response
case WMRZ_EGFX_CONN_CLOSING:
rdp = wm->session->rdp;
sec = rdp->sec_layer;
chan = sec->chan_layer;
// Continue to check to see if the connection is closed. If it case WMRZ_EGFX_RESET_GRAPHICS:
// ever is, advance the state machine! // EGFX only. Delete the surfaces and send a 'reset graphics'
if (chan->drdynvcs[mm->egfx->channel_id].status // command to resize the client. For EGFX, that's all we
== XRDP_DRDYNVC_STATUS_CLOSED // need to do.
|| (g_get_elapsed_ms() - description->last_state_update_timestamp) > 100) xrdp_mm_egfx_delete_surfaces(mm);
error = xrdp_egfx_send_reset_graphics(mm->egfx,
desc_width, desc_height,
description->description.monitorCount,
description->description.minfo);
if (error != 0)
{ {
advance_resize_state_machine(mm, WMRZ_EGFX_CONN_CLOSED); LOG_DEVEL(LOG_LEVEL_INFO,
break; "process_display_control_monitor_layout_data:"
} " egfx_send_reset_graphics failed %d", error);
g_set_wait_obj(mm->resize_ready); return advance_error(error, mm);
break;
case WMRZ_EGFX_CONN_CLOSED:
advance_resize_state_machine(mm, WRMZ_EGFX_DELETE);
break;
case WRMZ_EGFX_DELETE:
if (error == 0 && module != 0)
{
xrdp_egfx_shutdown_delete(wm->mm->egfx);
mm->egfx = NULL;
} }
advance_resize_state_machine(mm, WMRZ_SERVER_MONITOR_RESIZE); advance_resize_state_machine(mm, WMRZ_SERVER_MONITOR_RESIZE);
break; break;
case WMRZ_SERVER_MONITOR_RESIZE: case WMRZ_SERVER_MONITOR_RESIZE:
error = module->mod_server_monitor_resize( error = module->mod_server_monitor_resize(
module, desc_width, desc_height, module, desc_width, desc_height,
@@ -1743,10 +1734,23 @@ process_display_control_monitor_layout_data(struct xrdp_wm *wm)
// Not processed here. Processed in client_monitor_resize // Not processed here. Processed in client_monitor_resize
// case WMRZ_SERVER_MONITOR_MESSAGE_PROCESSING: // case WMRZ_SERVER_MONITOR_MESSAGE_PROCESSING:
case WMRZ_SERVER_MONITOR_MESSAGE_PROCESSED: case WMRZ_SERVER_MONITOR_MESSAGE_PROCESSED:
advance_resize_state_machine(mm, WMRZ_XRDP_CORE_RESET); // Update the wm with the layout from the description
break; // we're processing
case WMRZ_XRDP_CORE_RESET:
sync_dynamic_monitor_data(wm, &(description->description)); sync_dynamic_monitor_data(wm, &(description->description));
if (!mm->egfx_up)
{
// Need to resize the client using deactivation-reactivation
// sequence
advance_resize_state_machine(mm, WMRZ_XRDP_CORE_RESET);
}
else
{
// Client is already resized
advance_resize_state_machine(mm, WMRZ_ENCODER_CREATE);
}
break;
case WMRZ_XRDP_CORE_RESET:
error = libxrdp_reset(wm->session); error = libxrdp_reset(wm->session);
if (error != 0) if (error != 0)
{ {
@@ -1788,7 +1792,21 @@ process_display_control_monitor_layout_data(struct xrdp_wm *wm)
" xrdp_wm_load_static_pointers failed %d", error); " xrdp_wm_load_static_pointers failed %d", error);
return advance_error(error, mm); return advance_error(error, mm);
} }
/* resize the main window */ advance_resize_state_machine(mm, WMRZ_ENCODER_CREATE);
break;
case WMRZ_ENCODER_CREATE:
if (mm->egfx_up)
{
xrdp_mm_egfx_create_surfaces(mm);
}
mm->encoder = xrdp_encoder_create(mm);
// Ack all frames to speed up resize.
module->mod_frame_ack(module, 0, INT_MAX);
// Restart module output after resizing and invalidating
// the screen. This causes an automatic redraw.
error = xrdp_bitmap_resize( error = xrdp_bitmap_resize(
wm->screen, desc_width, desc_height); wm->screen, desc_width, desc_height);
if (error != 0) if (error != 0)
@@ -1798,42 +1816,8 @@ process_display_control_monitor_layout_data(struct xrdp_wm *wm)
" xrdp_bitmap_resize failed %d", error); " xrdp_bitmap_resize failed %d", error);
return advance_error(error, mm); return advance_error(error, mm);
} }
advance_resize_state_machine(mm, WMRZ_EGFX_INITIALIZE);
break;
case WMRZ_EGFX_INITIALIZE:
if (mm->resize_data->using_egfx)
{
egfx_initialize(mm);
advance_resize_state_machine(mm, WMRZ_EGFX_INITALIZING);
}
else
{
advance_resize_state_machine(mm, WMRZ_EGFX_INITIALIZED);
}
break;
// Not processed here. Processed in xrdp_mm_egfx_caps_advertise
// case WMRZ_EGFX_INITALIZING:
case WMRZ_EGFX_INITIALIZED:
advance_resize_state_machine(mm, WMRZ_ENCODER_CREATE);
break;
case WMRZ_ENCODER_CREATE:
if (mm->encoder == NULL)
{
mm->encoder = xrdp_encoder_create(mm);
}
advance_resize_state_machine(mm, WMRZ_SERVER_INVALIDATE);
break;
case WMRZ_SERVER_INVALIDATE:
if (module != 0)
{
// Ack all frames to speed up resize.
module->mod_frame_ack(module, 0, INT_MAX);
}
// Restart module output after invalidating
// the screen. This causes an automatic redraw.
xrdp_bitmap_invalidate(wm->screen, 0); xrdp_bitmap_invalidate(wm->screen, 0);
rdp = wm->session->rdp; xrdp_rdp_suppress_output(wm->session->rdp,
xrdp_rdp_suppress_output(rdp,
0, XSO_REASON_DYNAMIC_RESIZE, 0, XSO_REASON_DYNAMIC_RESIZE,
0, 0, desc_width, desc_height); 0, 0, desc_width, desc_height);
advance_resize_state_machine(mm, WMRZ_COMPLETE); advance_resize_state_machine(mm, WMRZ_COMPLETE);
@@ -1930,7 +1914,6 @@ dynamic_monitor_process_queue(struct xrdp_mm *self)
const unsigned int time = g_get_elapsed_ms(); const unsigned int time = g_get_elapsed_ms();
self->resize_data->start_time = time; self->resize_data->start_time = time;
self->resize_data->last_state_update_timestamp = time; self->resize_data->last_state_update_timestamp = time;
self->resize_data->using_egfx = (self->egfx != NULL);
advance_resize_state_machine(self, WMRZ_ENCODER_DELETE); advance_resize_state_machine(self, WMRZ_ENCODER_DELETE);
} }
else else
+2 -16
View File
@@ -356,20 +356,13 @@ enum mm_connect_state
enum display_resize_state enum display_resize_state
{ {
WMRZ_ENCODER_DELETE = 0, WMRZ_ENCODER_DELETE = 0,
WMRZ_EGFX_DELETE_SURFACE, WMRZ_EGFX_RESET_GRAPHICS,
WMRZ_EGFX_CONN_CLOSE,
WMRZ_EGFX_CONN_CLOSING,
WMRZ_EGFX_CONN_CLOSED,
WRMZ_EGFX_DELETE,
WMRZ_SERVER_MONITOR_RESIZE, WMRZ_SERVER_MONITOR_RESIZE,
WMRZ_SERVER_MONITOR_MESSAGE_PROCESSING, WMRZ_SERVER_MONITOR_MESSAGE_PROCESSING,
WMRZ_SERVER_MONITOR_MESSAGE_PROCESSED, WMRZ_SERVER_MONITOR_MESSAGE_PROCESSED,
WMRZ_XRDP_CORE_RESET, WMRZ_XRDP_CORE_RESET,
WMRZ_XRDP_CORE_RESET_PROCESSING, WMRZ_XRDP_CORE_RESET_PROCESSING,
WMRZ_XRDP_CORE_RESET_PROCESSED, WMRZ_XRDP_CORE_RESET_PROCESSED,
WMRZ_EGFX_INITIALIZE,
WMRZ_EGFX_INITALIZING,
WMRZ_EGFX_INITIALIZED,
WMRZ_ENCODER_CREATE, WMRZ_ENCODER_CREATE,
WMRZ_SERVER_INVALIDATE, WMRZ_SERVER_INVALIDATE,
WMRZ_COMPLETE, WMRZ_COMPLETE,
@@ -378,11 +371,7 @@ enum display_resize_state
#define XRDP_DISPLAY_RESIZE_STATE_TO_STR(status) \ #define XRDP_DISPLAY_RESIZE_STATE_TO_STR(status) \
((status) == WMRZ_ENCODER_DELETE ? "WMRZ_ENCODER_DELETE" : \ ((status) == WMRZ_ENCODER_DELETE ? "WMRZ_ENCODER_DELETE" : \
(status) == WMRZ_EGFX_DELETE_SURFACE ? "WMRZ_EGFX_DELETE_SURFACE" : \ (status) == WMRZ_EGFX_RESET_GRAPHICS ? "WMRZ_EGFX_RESET_GRAPHICS" : \
(status) == WMRZ_EGFX_CONN_CLOSE ? "WMRZ_EGFX_CONN_CLOSE" : \
(status) == WMRZ_EGFX_CONN_CLOSING ? "WMRZ_EGFX_CONN_CLOSING" : \
(status) == WMRZ_EGFX_CONN_CLOSED ? "WMRZ_EGFX_CONN_CLOSED" : \
(status) == WRMZ_EGFX_DELETE ? "WMRZ_EGFX_DELETE" : \
(status) == WMRZ_SERVER_MONITOR_RESIZE ? "WMRZ_SERVER_MONITOR_RESIZE" : \ (status) == WMRZ_SERVER_MONITOR_RESIZE ? "WMRZ_SERVER_MONITOR_RESIZE" : \
(status) == WMRZ_SERVER_MONITOR_MESSAGE_PROCESSING ? \ (status) == WMRZ_SERVER_MONITOR_MESSAGE_PROCESSING ? \
"WMRZ_SERVER_MONITOR_MESSAGE_PROCESSING" : \ "WMRZ_SERVER_MONITOR_MESSAGE_PROCESSING" : \
@@ -393,9 +382,6 @@ enum display_resize_state
"WMRZ_XRDP_CORE_RESET_PROCESSING" : \ "WMRZ_XRDP_CORE_RESET_PROCESSING" : \
(status) == WMRZ_XRDP_CORE_RESET_PROCESSED ? \ (status) == WMRZ_XRDP_CORE_RESET_PROCESSED ? \
"WMRZ_XRDP_CORE_RESET_PROCESSED" : \ "WMRZ_XRDP_CORE_RESET_PROCESSED" : \
(status) == WMRZ_EGFX_INITIALIZE ? "WMRZ_EGFX_INITIALIZE" : \
(status) == WMRZ_EGFX_INITALIZING ? "WMRZ_EGFX_INITALIZING" : \
(status) == WMRZ_EGFX_INITIALIZED ? "WMRZ_EGFX_INITIALIZED" : \
(status) == WMRZ_ENCODER_CREATE ? "WMRZ_ENCODER_CREATE" : \ (status) == WMRZ_ENCODER_CREATE ? "WMRZ_ENCODER_CREATE" : \
(status) == WMRZ_SERVER_INVALIDATE ? "WMRZ_SERVER_INVALIDATE" : \ (status) == WMRZ_SERVER_INVALIDATE ? "WMRZ_SERVER_INVALIDATE" : \
(status) == WMRZ_COMPLETE ? "WMRZ_COMPLETE" : \ (status) == WMRZ_COMPLETE ? "WMRZ_COMPLETE" : \