mirror of https://github.com/FreeRDP/FreeRDP
shadow: make use of synchronization barrier
This commit is contained in:
parent
edde16e9d5
commit
8b4cf07c8a
|
@ -113,7 +113,9 @@ struct rdp_shadow_server
|
|||
int monitorCount; \
|
||||
MONITOR_DEF monitors[16]; \
|
||||
MONITOR_DEF virtualScreen; \
|
||||
HANDLE updateEvent; \
|
||||
REGION16 invalidRegion; \
|
||||
SYNCHRONIZATION_BARRIER barrier; \
|
||||
\
|
||||
pfnShadowSubsystemInit Init; \
|
||||
pfnShadowSubsystemUninit Uninit; \
|
||||
|
|
|
@ -1072,6 +1072,8 @@ void win_shadow_subsystem_free(winShadowSubsystem* subsystem)
|
|||
|
||||
region16_uninit(&(subsystem->invalidRegion));
|
||||
|
||||
CloseHandle(subsystem->updateEvent);
|
||||
|
||||
free(subsystem);
|
||||
}
|
||||
|
||||
|
@ -1086,6 +1088,8 @@ winShadowSubsystem* win_shadow_subsystem_new(rdpShadowServer* server)
|
|||
|
||||
subsystem->server = server;
|
||||
|
||||
subsystem->updateEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
region16_init(&(subsystem->invalidRegion));
|
||||
|
||||
subsystem->Init = (pfnShadowSubsystemInit) win_shadow_subsystem_init;
|
||||
|
|
|
@ -187,6 +187,7 @@ int x11_shadow_invalidate_region(x11ShadowSubsystem* subsystem, int x, int y, in
|
|||
|
||||
int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
|
||||
{
|
||||
int count;
|
||||
int status;
|
||||
int x, y;
|
||||
int width, height;
|
||||
|
@ -200,18 +201,18 @@ int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
|
|||
surface = server->surface;
|
||||
screen = server->screen;
|
||||
|
||||
XLockDisplay(subsystem->display);
|
||||
|
||||
if (subsystem->use_xshm)
|
||||
{
|
||||
XLockDisplay(subsystem->display);
|
||||
|
||||
XCopyArea(subsystem->display, subsystem->root_window, subsystem->fb_pixmap,
|
||||
subsystem->xshm_gc, 0, 0, subsystem->width, subsystem->height, 0, 0);
|
||||
|
||||
XSync(subsystem->display, False);
|
||||
|
||||
image = subsystem->fb_image;
|
||||
XUnlockDisplay(subsystem->display);
|
||||
|
||||
EnterCriticalSection(&(screen->lock));
|
||||
image = subsystem->fb_image;
|
||||
|
||||
status = shadow_capture_compare(surface->data, surface->scanline, surface->width, surface->height,
|
||||
(BYTE*) image->data, image->bytes_per_line, &invalidRect);
|
||||
|
@ -230,20 +231,29 @@ int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
|
|||
|
||||
region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &invalidRect);
|
||||
|
||||
if (subsystem->SurfaceUpdate)
|
||||
subsystem->SurfaceUpdate((rdpShadowSubsystem*) subsystem, &(subsystem->invalidRegion));
|
||||
count = ArrayList_Count(server->clients);
|
||||
|
||||
InitializeSynchronizationBarrier(&(subsystem->barrier), count + 1, -1);
|
||||
|
||||
SetEvent(subsystem->updateEvent);
|
||||
|
||||
EnterSynchronizationBarrier(&(subsystem->barrier), 0);
|
||||
|
||||
DeleteSynchronizationBarrier(&(subsystem->barrier));
|
||||
|
||||
ResetEvent(subsystem->updateEvent);
|
||||
|
||||
region16_clear(&(subsystem->invalidRegion));
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&(screen->lock));
|
||||
}
|
||||
else
|
||||
{
|
||||
XLockDisplay(subsystem->display);
|
||||
|
||||
image = XGetImage(subsystem->display, subsystem->root_window,
|
||||
0, 0, subsystem->width, subsystem->height, AllPlanes, ZPixmap);
|
||||
|
||||
EnterCriticalSection(&(screen->lock));
|
||||
XUnlockDisplay(subsystem->display);
|
||||
|
||||
status = shadow_capture_compare(surface->data, surface->scanline, surface->width, surface->height,
|
||||
(BYTE*) image->data, image->bytes_per_line, &invalidRect);
|
||||
|
@ -262,19 +272,24 @@ int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
|
|||
|
||||
region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &invalidRect);
|
||||
|
||||
if (subsystem->SurfaceUpdate)
|
||||
subsystem->SurfaceUpdate((rdpShadowSubsystem*) subsystem, &(subsystem->invalidRegion));
|
||||
count = ArrayList_Count(server->clients);
|
||||
|
||||
InitializeSynchronizationBarrier(&(subsystem->barrier), count + 1, -1);
|
||||
|
||||
SetEvent(subsystem->updateEvent);
|
||||
|
||||
EnterSynchronizationBarrier(&(subsystem->barrier), 0);
|
||||
|
||||
DeleteSynchronizationBarrier(&(subsystem->barrier));
|
||||
|
||||
ResetEvent(subsystem->updateEvent);
|
||||
|
||||
region16_clear(&(subsystem->invalidRegion));
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&(screen->lock));
|
||||
|
||||
XDestroyImage(image);
|
||||
}
|
||||
|
||||
XUnlockDisplay(subsystem->display);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -299,7 +314,7 @@ void* x11_shadow_subsystem_thread(x11ShadowSubsystem* subsystem)
|
|||
events[nCount++] = StopEvent;
|
||||
events[nCount++] = subsystem->event;
|
||||
|
||||
fps = 24;
|
||||
fps = 16;
|
||||
dwInterval = 1000 / fps;
|
||||
frameTime = GetTickCount64() + dwInterval;
|
||||
|
||||
|
@ -749,6 +764,8 @@ void x11_shadow_subsystem_free(x11ShadowSubsystem* subsystem)
|
|||
|
||||
region16_uninit(&(subsystem->invalidRegion));
|
||||
|
||||
CloseHandle(subsystem->updateEvent);
|
||||
|
||||
free(subsystem);
|
||||
}
|
||||
|
||||
|
@ -763,6 +780,8 @@ x11ShadowSubsystem* x11_shadow_subsystem_new(rdpShadowServer* server)
|
|||
|
||||
subsystem->server = server;
|
||||
|
||||
subsystem->updateEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
region16_init(&(subsystem->invalidRegion));
|
||||
|
||||
subsystem->Init = (pfnShadowSubsystemInit) x11_shadow_subsystem_init;
|
||||
|
|
|
@ -613,17 +613,13 @@ int shadow_client_surface_update(rdpShadowClient* client, REGION16* region)
|
|||
|
||||
void* shadow_client_thread(rdpShadowClient* client)
|
||||
{
|
||||
int fps;
|
||||
DWORD status;
|
||||
DWORD nCount;
|
||||
UINT64 cTime;
|
||||
DWORD dwTimeout;
|
||||
DWORD dwInterval;
|
||||
UINT64 frameTime;
|
||||
HANDLE events[32];
|
||||
HANDLE StopEvent;
|
||||
HANDLE ClientEvent;
|
||||
HANDLE ChannelEvent;
|
||||
HANDLE UpdateEvent;
|
||||
freerdp_peer* peer;
|
||||
rdpSettings* settings;
|
||||
rdpShadowServer* server;
|
||||
|
@ -651,11 +647,8 @@ void* shadow_client_thread(rdpShadowClient* client)
|
|||
shadow_client_surface_frame_acknowledge;
|
||||
peer->update->SuppressOutput = (pSuppressOutput) shadow_client_suppress_output;
|
||||
|
||||
fps = 16;
|
||||
dwInterval = 1000 / fps;
|
||||
frameTime = GetTickCount64() + dwInterval;
|
||||
|
||||
StopEvent = client->StopEvent;
|
||||
UpdateEvent = subsystem->updateEvent;
|
||||
ClientEvent = peer->GetEventHandle(peer);
|
||||
ChannelEvent = WTSVirtualChannelManagerGetEventHandle(client->vcm);
|
||||
|
||||
|
@ -663,19 +656,43 @@ void* shadow_client_thread(rdpShadowClient* client)
|
|||
{
|
||||
nCount = 0;
|
||||
events[nCount++] = StopEvent;
|
||||
events[nCount++] = UpdateEvent;
|
||||
events[nCount++] = ClientEvent;
|
||||
events[nCount++] = ChannelEvent;
|
||||
|
||||
cTime = GetTickCount64();
|
||||
dwTimeout = (DWORD) ((cTime > frameTime) ? 0 : frameTime - cTime);
|
||||
status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
|
||||
|
||||
status = WaitForMultipleObjects(nCount, events, FALSE, dwTimeout);
|
||||
|
||||
if (WaitForSingleObject(client->StopEvent, 0) == WAIT_OBJECT_0)
|
||||
if (WaitForSingleObject(StopEvent, 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
if (WaitForSingleObject(UpdateEvent, 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
EnterSynchronizationBarrier(&(subsystem->barrier), 0);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (WaitForSingleObject(UpdateEvent, 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
if (client->activated)
|
||||
{
|
||||
int index;
|
||||
int numRects = 0;
|
||||
const RECTANGLE_16* rects;
|
||||
|
||||
rects = region16_rects(&(subsystem->invalidRegion), &numRects);
|
||||
|
||||
for (index = 0; index < numRects; index++)
|
||||
{
|
||||
region16_union_rect(&(client->invalidRegion), &(client->invalidRegion), &rects[index]);
|
||||
}
|
||||
|
||||
shadow_client_send_surface_update(client);
|
||||
}
|
||||
|
||||
EnterSynchronizationBarrier(&(subsystem->barrier), 0);
|
||||
}
|
||||
|
||||
if (WaitForSingleObject(ClientEvent, 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
if (!peer->CheckFileDescriptor(peer))
|
||||
|
@ -693,22 +710,6 @@ void* shadow_client_thread(rdpShadowClient* client)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((status == WAIT_TIMEOUT) || (GetTickCount64() > frameTime))
|
||||
{
|
||||
if (client->activated)
|
||||
{
|
||||
EnterCriticalSection(&(screen->lock));
|
||||
|
||||
shadow_client_send_surface_update(client);
|
||||
|
||||
LeaveCriticalSection(&(screen->lock));
|
||||
}
|
||||
|
||||
fps = encoder->fps;
|
||||
dwInterval = 1000 / fps;
|
||||
frameTime += dwInterval;
|
||||
}
|
||||
}
|
||||
|
||||
peer->Disconnect(peer);
|
||||
|
|
Loading…
Reference in New Issue