Fixed surface locking for shadow server.

This commit is contained in:
akallabeth 2020-05-27 10:01:04 +02:00
parent cf7b9ca055
commit a38d6c53a6
3 changed files with 50 additions and 24 deletions

View File

@ -370,6 +370,7 @@ static void (^mac_capture_stream_handler)(
int width; int width;
int height; int height;
int nSrcStep; int nSrcStep;
BOOL empty;
BYTE* pSrcData; BYTE* pSrcData;
RECTANGLE_16 surfaceRect; RECTANGLE_16 surfaceRect;
const RECTANGLE_16* extents; const RECTANGLE_16* extents;
@ -381,14 +382,17 @@ static void (^mac_capture_stream_handler)(
if (count < 1) if (count < 1)
return; return;
EnterCriticalSection(&(surface->lock));
mac_shadow_capture_get_dirty_region(subsystem); mac_shadow_capture_get_dirty_region(subsystem);
surfaceRect.left = 0; surfaceRect.left = 0;
surfaceRect.top = 0; surfaceRect.top = 0;
surfaceRect.right = surface->width; surfaceRect.right = surface->width;
surfaceRect.bottom = surface->height; surfaceRect.bottom = surface->height;
region16_intersect_rect(&(surface->invalidRegion), &(surface->invalidRegion), &surfaceRect); region16_intersect_rect(&(surface->invalidRegion), &(surface->invalidRegion), &surfaceRect);
empty = region16_is_empty(&(surface->invalidRegion));
LeaveCriticalSection(&(surface->lock));
if (!region16_is_empty(&(surface->invalidRegion))) if (!empty)
{ {
extents = region16_extents(&(surface->invalidRegion)); extents = region16_extents(&(surface->invalidRegion));
x = extents->left; x = extents->left;
@ -410,13 +414,12 @@ static void (^mac_capture_stream_handler)(
pSrcData, PIXEL_FORMAT_BGRX32, nSrcStep, x, y, NULL, pSrcData, PIXEL_FORMAT_BGRX32, nSrcStep, x, y, NULL,
FREERDP_FLIP_NONE); FREERDP_FLIP_NONE);
} }
LeaveCriticalSection(&(surface->lock));
IOSurfaceUnlock(frameSurface, kIOSurfaceLockReadOnly, NULL); IOSurfaceUnlock(frameSurface, kIOSurfaceLockReadOnly, NULL);
ArrayList_Lock(server->clients); ArrayList_Lock(server->clients);
count = ArrayList_Count(server->clients); count = ArrayList_Count(server->clients);
EnterCriticalSection(&(surface->lock));
shadow_subsystem_frame_update(&subsystem->common); shadow_subsystem_frame_update(&subsystem->common);
LeaveCriticalSection(&(surface->lock));
if (count == 1) if (count == 1)
{ {
@ -430,7 +433,9 @@ static void (^mac_capture_stream_handler)(
} }
ArrayList_Unlock(server->clients); ArrayList_Unlock(server->clients);
EnterCriticalSection(&(surface->lock));
region16_clear(&(surface->invalidRegion)); region16_clear(&(surface->invalidRegion));
LeaveCriticalSection(&(surface->lock));
} }
if (status != kCGDisplayStreamFrameStatusFrameComplete) if (status != kCGDisplayStreamFrameStatusFrameComplete)

View File

@ -757,6 +757,7 @@ static int x11_shadow_error_handler_for_capture(Display* display, XErrorEvent* e
static int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem) static int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
{ {
int rc = 0;
int count; int count;
int status; int status;
int x, y; int x, y;
@ -774,10 +775,13 @@ static int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
if (count < 1) if (count < 1)
return 1; return 1;
EnterCriticalSection(&surface->lock);
surfaceRect.left = 0; surfaceRect.left = 0;
surfaceRect.top = 0; surfaceRect.top = 0;
surfaceRect.right = surface->width; surfaceRect.right = surface->width;
surfaceRect.bottom = surface->height; surfaceRect.bottom = surface->height;
LeaveCriticalSection(&surface->lock);
XLockDisplay(subsystem->display); XLockDisplay(subsystem->display);
/* /*
* Ignore BadMatch error during image capture. The screen size may be * Ignore BadMatch error during image capture. The screen size may be
@ -790,15 +794,26 @@ static int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
image = subsystem->fb_image; image = subsystem->fb_image;
XCopyArea(subsystem->display, subsystem->root_window, subsystem->fb_pixmap, XCopyArea(subsystem->display, subsystem->root_window, subsystem->fb_pixmap,
subsystem->xshm_gc, 0, 0, subsystem->width, subsystem->height, 0, 0); subsystem->xshm_gc, 0, 0, subsystem->width, subsystem->height, 0, 0);
EnterCriticalSection(&surface->lock);
status = shadow_capture_compare(surface->data, surface->scanline, surface->width, status = shadow_capture_compare(surface->data, surface->scanline, surface->width,
surface->height, (BYTE*)&(image->data[surface->width * 4]), surface->height, (BYTE*)&(image->data[surface->width * 4]),
image->bytes_per_line, &invalidRect); image->bytes_per_line, &invalidRect);
LeaveCriticalSection(&surface->lock);
} }
else else
{ {
EnterCriticalSection(&surface->lock);
image = XGetImage(subsystem->display, subsystem->root_window, surface->x, surface->y, image = XGetImage(subsystem->display, subsystem->root_window, surface->x, surface->y,
surface->width, surface->height, AllPlanes, ZPixmap); surface->width, surface->height, AllPlanes, ZPixmap);
if (image)
{
status = shadow_capture_compare(surface->data, surface->scanline, surface->width,
surface->height, (BYTE*)image->data,
image->bytes_per_line, &invalidRect);
}
LeaveCriticalSection(&surface->lock);
if (!image) if (!image)
{ {
/* /*
@ -807,10 +822,6 @@ static int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
*/ */
goto fail_capture; goto fail_capture;
} }
status = shadow_capture_compare(surface->data, surface->scanline, surface->width,
surface->height, (BYTE*)image->data, image->bytes_per_line,
&invalidRect);
} }
/* Restore the default error handler */ /* Restore the default error handler */
@ -820,25 +831,32 @@ static int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
if (status) if (status)
{ {
BOOL empty;
EnterCriticalSection(&surface->lock);
region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &invalidRect); region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &invalidRect);
region16_intersect_rect(&(surface->invalidRegion), &(surface->invalidRegion), &surfaceRect); region16_intersect_rect(&(surface->invalidRegion), &(surface->invalidRegion), &surfaceRect);
empty = region16_is_empty(&(surface->invalidRegion));
LeaveCriticalSection(&surface->lock);
if (!region16_is_empty(&(surface->invalidRegion))) if (!empty)
{ {
BOOL success;
EnterCriticalSection(&surface->lock);
extents = region16_extents(&(surface->invalidRegion)); extents = region16_extents(&(surface->invalidRegion));
x = extents->left; x = extents->left;
y = extents->top; y = extents->top;
width = extents->right - extents->left; width = extents->right - extents->left;
height = extents->bottom - extents->top; height = extents->bottom - extents->top;
success = freerdp_image_copy(surface->data, surface->format, surface->scanline, x, y,
if (!freerdp_image_copy(surface->data, surface->format, surface->scanline, x, y, width, width, height, (BYTE*)image->data, PIXEL_FORMAT_BGRX32,
height, (BYTE*)image->data, PIXEL_FORMAT_BGRX32, image->bytes_per_line, x, y, NULL, FREERDP_FLIP_NONE);
image->bytes_per_line, x, y, NULL, FREERDP_FLIP_NONE)) LeaveCriticalSection(&surface->lock);
if (!success)
goto fail_capture; goto fail_capture;
// x11_shadow_blend_cursor(subsystem); // x11_shadow_blend_cursor(subsystem);
count = ArrayList_Count(server->clients); count = ArrayList_Count(server->clients);
shadow_subsystem_frame_update((rdpShadowSubsystem*)subsystem); shadow_subsystem_frame_update(&subsystem->common);
if (count == 1) if (count == 1)
{ {
@ -850,23 +868,25 @@ static int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
shadow_encoder_preferred_fps(client->encoder); shadow_encoder_preferred_fps(client->encoder);
} }
EnterCriticalSection(&surface->lock);
region16_clear(&(surface->invalidRegion)); region16_clear(&(surface->invalidRegion));
LeaveCriticalSection(&surface->lock);
} }
} }
if (!subsystem->use_xshm) rc = 1;
XDestroyImage(image);
return 1;
fail_capture: fail_capture:
if (!subsystem->use_xshm && image) if (!subsystem->use_xshm && image)
XDestroyImage(image); XDestroyImage(image);
if (rc != 1)
{
XSetErrorHandler(NULL); XSetErrorHandler(NULL);
XSync(subsystem->display, False); XSync(subsystem->display, False);
XUnlockDisplay(subsystem->display); XUnlockDisplay(subsystem->display);
return 0; }
return rc;
} }
static int x11_shadow_subsystem_process_message(x11ShadowSubsystem* subsystem, wMessage* message) static int x11_shadow_subsystem_process_message(x11ShadowSubsystem* subsystem, wMessage* message)

View File

@ -1331,12 +1331,12 @@ static BOOL shadow_client_send_surface_update(rdpShadowClient* client, SHADOW_GF
region16_copy(&invalidRegion, &(client->invalidRegion)); region16_copy(&invalidRegion, &(client->invalidRegion));
region16_clear(&(client->invalidRegion)); region16_clear(&(client->invalidRegion));
LeaveCriticalSection(&(client->lock)); LeaveCriticalSection(&(client->lock));
EnterCriticalSection(&surface->lock);
rects = region16_rects(&(surface->invalidRegion), &numRects); rects = region16_rects(&(surface->invalidRegion), &numRects);
for (index = 0; index < numRects; index++) for (index = 0; index < numRects; index++)
{
region16_union_rect(&invalidRegion, &invalidRegion, &rects[index]); region16_union_rect(&invalidRegion, &invalidRegion, &rects[index]);
}
surfaceRect.left = 0; surfaceRect.left = 0;
surfaceRect.top = 0; surfaceRect.top = 0;
@ -1410,6 +1410,7 @@ static BOOL shadow_client_send_surface_update(rdpShadowClient* client, SHADOW_GF
} }
out: out:
LeaveCriticalSection(&surface->lock);
region16_uninit(&invalidRegion); region16_uninit(&invalidRegion);
return ret; return ret;
} }