shadow: improve invalid region detection
This commit is contained in:
parent
d9d9bf3609
commit
fdab87cba0
@ -185,85 +185,6 @@ int x11_shadow_invalidate_region(x11ShadowSubsystem* subsystem, int x, int y, in
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x11_shadow_surface_copy(x11ShadowSubsystem* subsystem)
|
||||
{
|
||||
int x, y;
|
||||
int width;
|
||||
int height;
|
||||
XImage* image;
|
||||
rdpShadowScreen* screen;
|
||||
rdpShadowServer* server;
|
||||
rdpShadowSurface* surface;
|
||||
RECTANGLE_16 surfaceRect;
|
||||
const RECTANGLE_16* extents;
|
||||
|
||||
server = subsystem->server;
|
||||
surface = server->surface;
|
||||
screen = server->screen;
|
||||
|
||||
surfaceRect.left = surface->x;
|
||||
surfaceRect.top = surface->y;
|
||||
surfaceRect.right = surface->x + surface->width;
|
||||
surfaceRect.bottom = surface->y + surface->height;
|
||||
|
||||
region16_clear(&(surface->invalidRegion));
|
||||
region16_copy(&(surface->invalidRegion), &(subsystem->invalidRegion));
|
||||
region16_intersect_rect(&(surface->invalidRegion), &(surface->invalidRegion), &surfaceRect);
|
||||
|
||||
if (region16_is_empty(&(surface->invalidRegion)))
|
||||
return 1;
|
||||
|
||||
extents = region16_extents(&(surface->invalidRegion));
|
||||
|
||||
x = extents->left;
|
||||
y = extents->top;
|
||||
width = extents->right - extents->left;
|
||||
height = extents->bottom - extents->top;
|
||||
|
||||
XLockDisplay(subsystem->display);
|
||||
|
||||
if (subsystem->use_xshm)
|
||||
{
|
||||
XCopyArea(subsystem->display, subsystem->root_window, subsystem->fb_pixmap,
|
||||
subsystem->xshm_gc, x, y, width, height, x, y);
|
||||
|
||||
XSync(subsystem->display, False);
|
||||
|
||||
image = subsystem->fb_image;
|
||||
|
||||
EnterCriticalSection(&(surface->lock));
|
||||
|
||||
freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32,
|
||||
surface->scanline, x - surface->x, y - surface->y, width, height,
|
||||
(BYTE*) image->data, PIXEL_FORMAT_XRGB32,
|
||||
image->bytes_per_line, x, y);
|
||||
|
||||
LeaveCriticalSection(&(surface->lock));
|
||||
}
|
||||
else
|
||||
{
|
||||
image = XGetImage(subsystem->display, subsystem->root_window,
|
||||
x, y, width, height, AllPlanes, ZPixmap);
|
||||
|
||||
EnterCriticalSection(&(surface->lock));
|
||||
|
||||
freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32,
|
||||
surface->scanline, x - surface->x, y - surface->y, width, height,
|
||||
(BYTE*) image->data, PIXEL_FORMAT_XRGB32,
|
||||
image->bytes_per_line, 0, 0);
|
||||
|
||||
LeaveCriticalSection(&(surface->lock));
|
||||
|
||||
XDestroyImage(image);
|
||||
}
|
||||
|
||||
x11_shadow_validate_region(subsystem, x, y, width, height);
|
||||
|
||||
XUnlockDisplay(subsystem->display);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
|
||||
{
|
||||
int status;
|
||||
@ -290,7 +211,7 @@ int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
|
||||
|
||||
image = subsystem->fb_image;
|
||||
|
||||
EnterCriticalSection(&(surface->lock));
|
||||
EnterCriticalSection(&(screen->lock));
|
||||
|
||||
status = shadow_capture_compare(surface->data, surface->scanline, surface->width, surface->height,
|
||||
(BYTE*) image->data, image->bytes_per_line, &invalidRect);
|
||||
@ -302,28 +223,27 @@ int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
|
||||
width = invalidRect.right - invalidRect.left;
|
||||
height = invalidRect.bottom - invalidRect.top;
|
||||
|
||||
if (width > subsystem->width)
|
||||
width = subsystem->width;
|
||||
|
||||
if (height > subsystem->height)
|
||||
height = subsystem->height;
|
||||
|
||||
freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32,
|
||||
surface->scanline, x - surface->x, y - surface->y, width, height,
|
||||
(BYTE*) image->data, PIXEL_FORMAT_XRGB32,
|
||||
image->bytes_per_line, x, y);
|
||||
|
||||
x11_shadow_invalidate_region(subsystem, x, y, width, height);
|
||||
region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &invalidRect);
|
||||
|
||||
if (subsystem->SurfaceUpdate)
|
||||
subsystem->SurfaceUpdate((rdpShadowSubsystem*) subsystem, &(subsystem->invalidRegion));
|
||||
|
||||
region16_clear(&(subsystem->invalidRegion));
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&(surface->lock));
|
||||
LeaveCriticalSection(&(screen->lock));
|
||||
}
|
||||
else
|
||||
{
|
||||
image = XGetImage(subsystem->display, subsystem->root_window,
|
||||
0, 0, subsystem->width, subsystem->height, AllPlanes, ZPixmap);
|
||||
|
||||
EnterCriticalSection(&(surface->lock));
|
||||
EnterCriticalSection(&(screen->lock));
|
||||
|
||||
status = shadow_capture_compare(surface->data, surface->scanline, surface->width, surface->height,
|
||||
(BYTE*) image->data, image->bytes_per_line, &invalidRect);
|
||||
@ -335,21 +255,20 @@ int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
|
||||
width = invalidRect.right - invalidRect.left;
|
||||
height = invalidRect.bottom - invalidRect.top;
|
||||
|
||||
if (width > subsystem->width)
|
||||
width = subsystem->width;
|
||||
|
||||
if (height > subsystem->height)
|
||||
height = subsystem->height;
|
||||
|
||||
freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32,
|
||||
surface->scanline, x, y, width, height,
|
||||
surface->scanline, x - surface->x, y - surface->y, width, height,
|
||||
(BYTE*) image->data, PIXEL_FORMAT_XRGB32,
|
||||
image->bytes_per_line, x, y);
|
||||
|
||||
x11_shadow_invalidate_region(subsystem, x, y, width, height);
|
||||
region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &invalidRect);
|
||||
|
||||
if (subsystem->SurfaceUpdate)
|
||||
subsystem->SurfaceUpdate((rdpShadowSubsystem*) subsystem, &(subsystem->invalidRegion));
|
||||
|
||||
region16_clear(&(subsystem->invalidRegion));
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&(surface->lock));
|
||||
LeaveCriticalSection(&(screen->lock));
|
||||
|
||||
XDestroyImage(image);
|
||||
}
|
||||
@ -380,13 +299,10 @@ void* x11_shadow_subsystem_thread(x11ShadowSubsystem* subsystem)
|
||||
events[nCount++] = StopEvent;
|
||||
events[nCount++] = subsystem->event;
|
||||
|
||||
fps = 16;
|
||||
fps = 24;
|
||||
dwInterval = 1000 / fps;
|
||||
frameTime = GetTickCount64() + dwInterval;
|
||||
|
||||
//x11_shadow_invalidate_region(subsystem, 0, 0, subsystem->width, subsystem->height);
|
||||
//x11_shadow_surface_copy(subsystem);
|
||||
|
||||
while (1)
|
||||
{
|
||||
dwTimeout = INFINITE;
|
||||
@ -428,17 +344,6 @@ void* x11_shadow_subsystem_thread(x11ShadowSubsystem* subsystem)
|
||||
{
|
||||
x11_shadow_screen_grab(subsystem);
|
||||
|
||||
if (0)
|
||||
{
|
||||
x11_shadow_invalidate_region(subsystem, 0, 0, subsystem->width, subsystem->height);
|
||||
x11_shadow_surface_copy(subsystem);
|
||||
}
|
||||
|
||||
if (subsystem->SurfaceUpdate)
|
||||
subsystem->SurfaceUpdate((rdpShadowSubsystem*) subsystem, &(subsystem->invalidRegion));
|
||||
|
||||
region16_clear(&(subsystem->invalidRegion));
|
||||
|
||||
dwInterval = 1000 / fps;
|
||||
frameTime += dwInterval;
|
||||
}
|
||||
@ -866,8 +771,6 @@ x11ShadowSubsystem* x11_shadow_subsystem_new(rdpShadowServer* server)
|
||||
subsystem->Stop = (pfnShadowSubsystemStop) x11_shadow_subsystem_stop;
|
||||
subsystem->Free = (pfnShadowSubsystemFree) x11_shadow_subsystem_free;
|
||||
|
||||
subsystem->SurfaceCopy = (pfnShadowSurfaceCopy) x11_shadow_surface_copy;
|
||||
|
||||
subsystem->SynchronizeEvent = (pfnShadowSynchronizeEvent) x11_shadow_input_synchronize_event;
|
||||
subsystem->KeyboardEvent = (pfnShadowKeyboardEvent) x11_shadow_input_keyboard_event;
|
||||
subsystem->UnicodeKeyboardEvent = (pfnShadowUnicodeKeyboardEvent) x11_shadow_input_unicode_keyboard_event;
|
||||
|
@ -57,19 +57,26 @@ int shadow_capture_compare(BYTE* pData1, int nStep1, int nWidth, int nHeight, BY
|
||||
|
||||
for (ty = 0; ty < nrow; ty++)
|
||||
{
|
||||
th = ((ty + 1) == nrow) ? nHeight % 16 : 16;
|
||||
th = ((ty + 1) == nrow) ? (nHeight % 16) : 16;
|
||||
|
||||
if (!th)
|
||||
th = 16;
|
||||
|
||||
for (tx = 0; tx < ncol; tx++)
|
||||
{
|
||||
equal = TRUE;
|
||||
tw = ((tx + 1) == ncol) ? nWidth % 16 : 16;
|
||||
|
||||
tw = ((tx + 1) == ncol) ? (nWidth % 16) : 16;
|
||||
|
||||
if (!tw)
|
||||
tw = 16;
|
||||
|
||||
p1 = &pData1[(ty * 16 * nStep1) + (tx * 16 * 4)];
|
||||
p2 = &pData2[(ty * 16 * nStep2) + (tx * 16 * 4)];
|
||||
|
||||
for (k = 0; k < th; k++)
|
||||
{
|
||||
if (memcmp(p1, p2, tw) != 0)
|
||||
if (memcmp(p1, p2, tw * 4) != 0)
|
||||
{
|
||||
equal = FALSE;
|
||||
break;
|
||||
@ -113,6 +120,12 @@ int shadow_capture_compare(BYTE* pData1, int nStep1, int nWidth, int nHeight, BY
|
||||
rect->right = (r + 1) * 16;
|
||||
rect->bottom = (b + 1) * 16;
|
||||
|
||||
if (rect->right > nWidth)
|
||||
rect->right = nWidth;
|
||||
|
||||
if (rect->bottom > nHeight)
|
||||
rect->bottom = nHeight;
|
||||
|
||||
if (0)
|
||||
{
|
||||
printf("\n");
|
||||
|
@ -103,6 +103,7 @@ BOOL shadow_client_capabilities(freerdp_peer* peer)
|
||||
|
||||
BOOL shadow_client_post_connect(freerdp_peer* peer)
|
||||
{
|
||||
int width, height;
|
||||
rdpSettings* settings;
|
||||
rdpShadowClient* client;
|
||||
rdpShadowSurface* lobby;
|
||||
@ -124,7 +125,17 @@ BOOL shadow_client_post_connect(freerdp_peer* peer)
|
||||
|
||||
shadow_client_channels_post_connect(client);
|
||||
|
||||
lobby = client->lobby = shadow_surface_new(client->server, 0, 0, settings->DesktopWidth, settings->DesktopHeight);
|
||||
width = settings->DesktopWidth;
|
||||
height = settings->DesktopHeight;
|
||||
|
||||
invalidRect.left = 0;
|
||||
invalidRect.top = 0;
|
||||
invalidRect.right = width;
|
||||
invalidRect.bottom = height;
|
||||
|
||||
region16_union_rect(&(client->invalidRegion), &(client->invalidRegion), &invalidRect);
|
||||
|
||||
lobby = client->lobby = shadow_surface_new(client->server, 0, 0, width, height);
|
||||
|
||||
if (!client->lobby)
|
||||
return FALSE;
|
||||
@ -132,11 +143,6 @@ BOOL shadow_client_post_connect(freerdp_peer* peer)
|
||||
freerdp_image_fill(lobby->data, PIXEL_FORMAT_XRGB32, lobby->scanline,
|
||||
0, 0, lobby->width, lobby->height, 0x3BB9FF);
|
||||
|
||||
invalidRect.left = 0;
|
||||
invalidRect.top = 0;
|
||||
invalidRect.right = lobby->width;
|
||||
invalidRect.bottom = lobby->height;
|
||||
|
||||
region16_union_rect(&(lobby->invalidRegion), &(lobby->invalidRegion), &invalidRect);
|
||||
|
||||
return TRUE;
|
||||
@ -694,11 +700,7 @@ void* shadow_client_thread(rdpShadowClient* client)
|
||||
{
|
||||
EnterCriticalSection(&(screen->lock));
|
||||
|
||||
if (subsystem->SurfaceCopy)
|
||||
subsystem->SurfaceCopy(subsystem);
|
||||
|
||||
shadow_client_send_surface_update(client);
|
||||
region16_clear(&(screen->invalidRegion));
|
||||
|
||||
LeaveCriticalSection(&(screen->lock));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user