Skip to content

Commit

Permalink
limit dirty region complexity, remove no monitor list banding
Browse files Browse the repository at this point in the history
  • Loading branch information
jsorg71 committed Jul 16, 2024
1 parent e648dbf commit a183714
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 64 deletions.
1 change: 0 additions & 1 deletion module/rdpCapture.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ capture

/* maximum rects in the dirty region before the extents is used */
#define MAX_CAPTURE_RECTS 15
#define MAX_CAPTURE_PIXELS 0x800000

extern _X_EXPORT Bool
rdpCapture(rdpClientCon *clientCon, RegionPtr in_reg, BoxPtr *out_rects,
Expand Down
85 changes: 22 additions & 63 deletions module/rdpClientCon.c
Original file line number Diff line number Diff line change
Expand Up @@ -2826,9 +2826,7 @@ rdpClientConSendPaintRectShmFd(rdpPtr dev, rdpClientCon *clientCon,

/******************************************************************************/
/* this is called to capture a rect from the screen, if in a multi monitor
session, this will get called for each monitor, if no monitor info
from the client, the rect will be a band of less than MAX_CAPTURE_PIXELS
pixels
session, this will get called for each monitor
after the capture, it sends the info to xrdp
returns error */
static int
Expand All @@ -2838,16 +2836,26 @@ rdpCapRect(rdpClientCon *clientCon, BoxPtr cap_rect, int mon,
RegionPtr cap_dirty;
RegionPtr cap_dirty_save;
BoxPtr rects;
BoxRec rect;
int num_rects;

cap_dirty = rdpRegionCreate(cap_rect, 0);
LLOGLN(10, ("rdpCapRect: cap_rect x1 %d y1 %d x2 %d y2 %d",
cap_rect->x1, cap_rect->y1, cap_rect->x2, cap_rect->y2));
rdpRegionIntersect(cap_dirty, cap_dirty, clientCon->dirtyRegion);
num_rects = REGION_NUM_RECTS(cap_dirty);
if (num_rects > MAX_CAPTURE_RECTS)
{
/* the dirty region is too complex, just get a rect that
covers the whole region */
rect = *rdpRegionExtents(cap_dirty);
rdpRegionDestroy(cap_dirty);
cap_dirty = rdpRegionCreate(&rect, 0);
num_rects = REGION_NUM_RECTS(cap_dirty);
}
/* make a copy of cap_dirty because it may get altered */
cap_dirty_save = rdpRegionCreate(NullBox, 0);
rdpRegionCopy(cap_dirty_save, cap_dirty);
num_rects = REGION_NUM_RECTS(cap_dirty);
if (num_rects > 0)
{
rects = 0;
Expand Down Expand Up @@ -2888,13 +2896,7 @@ rdpDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg)
int index;
int monitor_index;
int monitor_count;
int band_index;
int band_count;
int band_height;
BoxRec cap_rect;
BoxRec dirty_extents;
int de_width;
int de_height;

LLOGLN(10, ("rdpDeferredUpdateCallback:"));
clientCon->updateScheduled = FALSE;
Expand All @@ -2919,61 +2921,18 @@ rdpDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg)
clientCon->lastUpdateTime = now;
LLOGLN(10, ("rdpDeferredUpdateCallback: sending"));
clientCon->updateRetries = 0;
rdpClientConGetScreenImageRect(clientCon->dev, clientCon, &id);
LLOGLN(10, ("rdpDeferredUpdateCallback: rdp_width %d rdp_height %d "
"rdp_Bpp %d screen width %d screen height %d",
clientCon->rdp_width, clientCon->rdp_height, clientCon->rdp_Bpp,
id.width, id.height));
if (clientCon->dev->monitorCount < 1)
{
dirty_extents = *rdpRegionExtents(clientCon->dirtyRegion);
dirty_extents.x1 = RDPMAX(dirty_extents.x1, 0);
dirty_extents.y1 = RDPMAX(dirty_extents.y1, 0);
dirty_extents.x2 = RDPMIN(dirty_extents.x2, clientCon->rdp_width);
dirty_extents.y2 = RDPMIN(dirty_extents.y2, clientCon->rdp_height);
LLOGLN(10, ("rdpDeferredUpdateCallback: dirty_extents %d %d %d %d",
dirty_extents.x1, dirty_extents.y1,
dirty_extents.x2, dirty_extents.y2));
de_width = dirty_extents.x2 - dirty_extents.x1;
de_height = dirty_extents.y2 - dirty_extents.y1;
if ((de_width > 0) && (de_height > 0))
{
band_height = MAX_CAPTURE_PIXELS / de_width;
band_index = 0;
band_count = (de_width * de_height / MAX_CAPTURE_PIXELS) + 1;
LLOGLN(10, ("rdpDeferredUpdateCallback: band_index %d "
"band_count %d", band_index, band_count));
while (band_index < band_count)
{
if (clientCon->rect_id > clientCon->rect_id_ack)
{
LLOGLN(10, ("rdpDeferredUpdateCallback: reschedule "
"rect_id %d rect_id_ack %d",
clientCon->rect_id, clientCon->rect_id_ack));
break;
}
index = (clientCon->rect_id + band_index) % band_count;
cap_rect.x1 = dirty_extents.x1;
cap_rect.y1 = dirty_extents.y1 + index * band_height;
cap_rect.x2 = dirty_extents.x2;
cap_rect.y2 = RDPMIN(cap_rect.y1 + band_height,
dirty_extents.y2);
rdpCapRect(clientCon, &cap_rect, 0, &id);
band_index++;
}
if (band_index == band_count)
{
/* gone through all bands, nothing changed */
rdpRegionDestroy(clientCon->dirtyRegion);
clientCon->dirtyRegion = rdpRegionCreate(NullBox, 0);
}
}
else
{
/* nothing changed in visible area */
rdpRegionDestroy(clientCon->dirtyRegion);
clientCon->dirtyRegion = rdpRegionCreate(NullBox, 0);
}
cap_rect.x1 = 0;
cap_rect.y1 = 0;
cap_rect.x2 = clientCon->rdp_width;
cap_rect.y2 = clientCon->rdp_height;
rdpClientConGetScreenImageRect(clientCon->dev, clientCon, &id);
id.left = cap_rect.x1;
id.top = cap_rect.y1;
id.width = cap_rect.x2 - cap_rect.x1;
id.height = cap_rect.y2 - cap_rect.y1;
rdpCapRect(clientCon, &cap_rect, 0, &id);
}
else
{
Expand Down

0 comments on commit a183714

Please sign in to comment.