shadow: start using message queue

This commit is contained in:
Marc-André Moreau 2014-09-18 17:22:44 -04:00
parent 7ef55ab9b7
commit aa7571648c
4 changed files with 95 additions and 47 deletions

View File

@ -85,6 +85,7 @@ struct rdp_shadow_client
rdpShadowServer* server;
rdpShadowSurface* lobby;
rdpShadowEncoder* encoder;
rdpShadowSubsystem* subsystem;
HANDLE vcm;
EncomspServerContext* encomsp;

View File

@ -199,7 +199,7 @@ list(APPEND ${MODULE_PREFIX}_LIBS winpr-makecert-tool)
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT server)
install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT server)
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Server/shadow")

View File

@ -431,6 +431,8 @@ int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
rdpShadowServer* server;
rdpShadowSurface* surface;
RECTANGLE_16 invalidRect;
RECTANGLE_16 surfaceRect;
const RECTANGLE_16 *extents;
server = subsystem->server;
surface = server->surface;
@ -441,6 +443,11 @@ int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
if (count < 1)
return 1;
surfaceRect.left = 0;
surfaceRect.top = 0;
surfaceRect.right = surface->width;
surfaceRect.bottom = surface->height;
if (subsystem->use_xshm)
{
XLockDisplay(subsystem->display);
@ -457,20 +464,23 @@ int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
status = shadow_capture_compare(surface->data, surface->scanline, surface->width, surface->height,
(BYTE*) &(image->data[surface->width * 4]), image->bytes_per_line, &invalidRect);
if (status > 0)
region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &invalidRect);
region16_intersect_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &surfaceRect);
if (!region16_is_empty(&(subsystem->invalidRegion)))
{
x = invalidRect.left;
y = invalidRect.top;
width = invalidRect.right - invalidRect.left;
height = invalidRect.bottom - invalidRect.top;
extents = region16_extents(&(subsystem->invalidRegion));
x = extents->left;
y = extents->top;
width = extents->right - extents->left;
height = extents->bottom - extents->top;
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, NULL);
region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &invalidRect);
x11_shadow_blend_cursor(subsystem);
count = ArrayList_Count(server->clients);
@ -500,20 +510,23 @@ int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
status = shadow_capture_compare(surface->data, surface->scanline, surface->width, surface->height,
(BYTE*) image->data, image->bytes_per_line, &invalidRect);
if (status > 0)
region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &invalidRect);
region16_intersect_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &surfaceRect);
if (!region16_is_empty(&(subsystem->invalidRegion)))
{
x = invalidRect.left;
y = invalidRect.top;
width = invalidRect.right - invalidRect.left;
height = invalidRect.bottom - invalidRect.top;
extents = region16_extents(&(subsystem->invalidRegion));
x = extents->left;
y = extents->top;
width = extents->right - extents->left;
height = extents->bottom - extents->top;
freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32,
surface->scanline, x, y, width, height,
(BYTE*) image->data, PIXEL_FORMAT_XRGB32,
image->bytes_per_line, x, y, NULL);
region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &invalidRect);
x11_shadow_blend_cursor(subsystem);
count = ArrayList_Count(server->clients);
@ -548,13 +561,14 @@ void* x11_shadow_subsystem_thread(x11ShadowSubsystem* subsystem)
DWORD dwInterval;
UINT64 frameTime;
HANDLE events[32];
HANDLE StopEvent;
wMessage message;
wMessagePipe* MsgPipe;
StopEvent = subsystem->server->StopEvent;
MsgPipe = subsystem->MsgPipe;
nCount = 0;
events[nCount++] = StopEvent;
events[nCount++] = subsystem->event;
events[nCount++] = MessageQueue_Event(MsgPipe->In);
fps = 16;
dwInterval = 1000 / fps;
@ -567,9 +581,25 @@ void* x11_shadow_subsystem_thread(x11ShadowSubsystem* subsystem)
status = WaitForMultipleObjects(nCount, events, FALSE, dwTimeout);
if (WaitForSingleObject(StopEvent, 0) == WAIT_OBJECT_0)
if (WaitForSingleObject(MessageQueue_Event(MsgPipe->In), 0) == WAIT_OBJECT_0)
{
break;
if (MessageQueue_Peek(MsgPipe->In, &message, TRUE))
{
if (message.id == WMQ_QUIT)
break;
if (message.id == 1)
{
RECTANGLE_16 refreshRect;
refreshRect.left = 0;
refreshRect.top = 0;
refreshRect.right = subsystem->width;
refreshRect.bottom = subsystem->height;
region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &refreshRect);
}
}
}
if (WaitForSingleObject(subsystem->event, 0) == WAIT_OBJECT_0)
@ -1015,12 +1045,10 @@ int x11_shadow_subsystem_uninit(x11ShadowSubsystem* subsystem)
int x11_shadow_subsystem_start(x11ShadowSubsystem* subsystem)
{
HANDLE thread;
if (!subsystem)
return -1;
thread = CreateThread(NULL, 0,
subsystem->thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) x11_shadow_subsystem_thread,
(void*) subsystem, 0, NULL);
@ -1032,19 +1060,17 @@ int x11_shadow_subsystem_stop(x11ShadowSubsystem* subsystem)
if (!subsystem)
return -1;
if (subsystem->thread)
{
MessageQueue_PostQuit(subsystem->MsgPipe->In, 0);
WaitForSingleObject(subsystem->thread, INFINITE);
CloseHandle(subsystem->thread);
subsystem->thread = NULL;
}
return 1;
}
void x11_shadow_subsystem_free(x11ShadowSubsystem* subsystem)
{
if (!subsystem)
return;
x11_shadow_subsystem_uninit(subsystem);
free(subsystem);
}
x11ShadowSubsystem* x11_shadow_subsystem_new()
{
x11ShadowSubsystem* subsystem;
@ -1069,6 +1095,16 @@ x11ShadowSubsystem* x11_shadow_subsystem_new()
return subsystem;
}
void x11_shadow_subsystem_free(x11ShadowSubsystem* subsystem)
{
if (!subsystem)
return;
x11_shadow_subsystem_uninit(subsystem);
free(subsystem);
}
int X11_ShadowSubsystemEntry(RDP_SHADOW_ENTRY_POINTS* pEntryPoints)
{
pEntryPoints->New = (pfnShadowSubsystemNew) x11_shadow_subsystem_new;

View File

@ -40,6 +40,7 @@ void shadow_client_context_new(freerdp_peer* peer, rdpShadowClient* client)
server = (rdpShadowServer*) peer->ContextExtra;
client->server = server;
client->subsystem = server->subsystem;
settings = peer->settings;
@ -165,6 +166,24 @@ BOOL shadow_client_post_connect(freerdp_peer* peer)
return TRUE;
}
void shadow_client_refresh_rect(rdpShadowClient* client, BYTE count, RECTANGLE_16* areas)
{
wMessagePipe* MsgPipe = client->subsystem->MsgPipe;
printf("RefreshRect: %d\n", count);
MessageQueue_Post(MsgPipe->In, (void*) client, 1, NULL, NULL);
}
void shadow_client_suppress_output(rdpShadowClient* client, BYTE allow, RECTANGLE_16* area)
{
wMessagePipe* MsgPipe = client->subsystem->MsgPipe;
printf("SuppressOutput: %d\n", allow);
MessageQueue_Post(MsgPipe->In, (void*) client, 2, NULL, NULL);
}
BOOL shadow_client_activate(freerdp_peer* peer)
{
rdpShadowClient* client;
@ -176,6 +195,8 @@ BOOL shadow_client_activate(freerdp_peer* peer)
shadow_encoder_reset(client->encoder);
shadow_client_refresh_rect(client, 0, NULL);
return TRUE;
}
@ -194,16 +215,6 @@ void shadow_client_surface_frame_acknowledge(rdpShadowClient* client, UINT32 fra
}
}
void shadow_client_refresh_rect(rdpContext* context, BYTE count, RECTANGLE_16* areas)
{
}
void shadow_client_suppress_output(rdpShadowClient* client, BYTE allow, RECTANGLE_16* area)
{
}
int shadow_client_send_surface_frame_marker(rdpShadowClient* client, UINT32 action, UINT32 id)
{
SURFACE_FRAME_MARKER surfaceFrameMarker;
@ -663,6 +674,7 @@ void* shadow_client_thread(rdpShadowClient* client)
HANDLE ChannelEvent;
HANDLE UpdateEvent;
freerdp_peer* peer;
rdpContext* context;
rdpSettings* settings;
rdpShadowServer* server;
rdpShadowScreen* screen;
@ -674,7 +686,8 @@ void* shadow_client_thread(rdpShadowClient* client)
encoder = client->encoder;
subsystem = server->subsystem;
peer = ((rdpContext*) client)->peer;
context = (rdpContext*) client;
peer = context->peer;
settings = peer->settings;
peer->Capabilities = shadow_client_capabilities;
@ -685,11 +698,9 @@ void* shadow_client_thread(rdpShadowClient* client)
peer->Initialize(peer);
peer->update->SurfaceFrameAcknowledge = (pSurfaceFrameAcknowledge)
shadow_client_surface_frame_acknowledge;
peer->update->RefreshRect = (pRefreshRect) shadow_client_refresh_rect;
peer->update->SuppressOutput = (pSuppressOutput) shadow_client_suppress_output;
peer->update->SurfaceFrameAcknowledge = (pSurfaceFrameAcknowledge) shadow_client_surface_frame_acknowledge;
StopEvent = client->StopEvent;
UpdateEvent = subsystem->updateEvent;