Merge pull request #5424 from kubistika/rdpgfx

rdpgfx: CacheImportOffer implementation
This commit is contained in:
David Fort 2019-06-13 11:35:15 +02:00 committed by GitHub
commit 2da425aa03
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 135 additions and 21 deletions

View File

@ -363,21 +363,40 @@ static UINT rdpgfx_send_frame_acknowledge_pdu(RdpgfxClientContext* context,
pdu->totalFramesDecoded); /* totalFramesDecoded (4 bytes) */
error = callback->channel->Write(callback->channel, (UINT32) Stream_Length(s),
Stream_Buffer(s), NULL);
if (error == CHANNEL_RC_OK) /* frame successfully acked */
gfx->UnacknowledgedFrames--;
fail:
Stream_Free(s, TRUE);
return error;
}
static UINT rdpgfx_send_qoe_frame_acknowledge_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
static UINT rdpgfx_send_qoe_frame_acknowledge_pdu(RdpgfxClientContext* context,
const RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU* pdu)
{
UINT error;
wStream* s;
RDPGFX_HEADER header;
RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin;
RDPGFX_CHANNEL_CALLBACK* callback;
RDPGFX_PLUGIN* gfx;
header.flags = 0;
header.cmdId = RDPGFX_CMDID_QOEFRAMEACKNOWLEDGE;
header.pduLength = RDPGFX_HEADER_SIZE + 12;
if (!context || !pdu)
return ERROR_BAD_ARGUMENTS;
gfx = (RDPGFX_PLUGIN*) context->handle;
if (!gfx)
return ERROR_BAD_CONFIGURATION;
callback = gfx->listener_callback->channel_callback;
if (!callback)
return ERROR_BAD_CONFIGURATION;
DEBUG_RDPGFX(gfx->log, "SendQoeFrameAcknowledgePdu: %"PRIu32"", pdu->frameId);
s = Stream_New(NULL, header.pduLength);
@ -402,6 +421,75 @@ fail:
return error;
}
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT rdpgfx_send_cache_import_offer_pdu(RdpgfxClientContext* context,
const RDPGFX_CACHE_IMPORT_OFFER_PDU* pdu)
{
UINT16 index;
UINT error = CHANNEL_RC_OK;
wStream* s;
RDPGFX_PLUGIN* gfx;
RDPGFX_CHANNEL_CALLBACK* callback;
RDPGFX_HEADER header;
RDPGFX_CACHE_ENTRY_METADATA* cacheEntries;
if (!context || !pdu)
return ERROR_BAD_ARGUMENTS;
gfx = (RDPGFX_PLUGIN*) context->handle;
if (!gfx)
return ERROR_BAD_CONFIGURATION;
callback = gfx->listener_callback->channel_callback;
if (!callback)
return ERROR_BAD_CONFIGURATION;
header.flags = 0;
header.cmdId = RDPGFX_CMDID_CACHEIMPORTOFFER;
header.pduLength = RDPGFX_HEADER_SIZE + 2 + pdu->cacheEntriesCount * 12;
DEBUG_RDPGFX(gfx->log, "SendCacheImportOfferPdu: cacheEntriesCount: %"PRIu16"", pdu->cacheEntriesCount);
s = Stream_New(NULL, header.pduLength);
if (!s)
{
WLog_ERR(TAG, "Stream_New failed!");
return CHANNEL_RC_NO_MEMORY;
}
if ((error = rdpgfx_write_header(s, &header)))
goto fail;
if (pdu->cacheEntriesCount <= 0)
{
WLog_ERR(TAG, "Invalid cacheEntriesCount: %"PRIu16"", pdu->cacheEntriesCount);
error = ERROR_INVALID_DATA;
goto fail;
}
/* cacheEntriesCount (2 bytes) */
Stream_Write_UINT16(s, pdu->cacheEntriesCount);
for (index = 0; index < pdu->cacheEntriesCount; index++)
{
cacheEntries = &(pdu->cacheEntries[index]);
Stream_Write_UINT64(s, cacheEntries->cacheKey); /* cacheKey (8 bytes) */
Stream_Write_UINT32(s, cacheEntries->bitmapLength); /* bitmapLength (4 bytes) */
}
error = callback->channel->Write(callback->channel, (UINT32) Stream_Length(s),
Stream_Buffer(s), NULL);
fail:
Stream_Free(s, TRUE);
return error;
}
/**
* Function description
*
@ -720,30 +808,30 @@ static UINT rdpgfx_recv_end_frame_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
}
}
gfx->UnacknowledgedFrames--;
gfx->TotalDecodedFrames++;
if (!gfx->sendFrameAcks)
return error;
ack.frameId = pdu.frameId;
ack.totalFramesDecoded = gfx->TotalDecodedFrames;
if (gfx->sendFrameAcks)
if (gfx->suspendFrameAcks)
{
if (gfx->suspendFrameAcks)
{
ack.queueDepth = SUSPEND_FRAME_ACKNOWLEDGEMENT;
if (gfx->TotalDecodedFrames == 1)
if ((error = rdpgfx_send_frame_acknowledge_pdu(context, &ack)))
WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_send_frame_acknowledge_pdu failed with error %"PRIu32"",
error);
}
else
{
ack.queueDepth = QUEUE_DEPTH_UNAVAILABLE;
ack.queueDepth = SUSPEND_FRAME_ACKNOWLEDGEMENT;
if (gfx->TotalDecodedFrames == 1)
if ((error = rdpgfx_send_frame_acknowledge_pdu(context, &ack)))
WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_send_frame_acknowledge_pdu failed with error %"PRIu32"",
error);
}
error);
}
else
{
ack.queueDepth = QUEUE_DEPTH_UNAVAILABLE;
if ((error = rdpgfx_send_frame_acknowledge_pdu(context, &ack)))
WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_send_frame_acknowledge_pdu failed with error %"PRIu32"",
error);
}
switch (gfx->ConnectionCaps.version)
@ -767,7 +855,7 @@ static UINT rdpgfx_recv_end_frame_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
qoe.timeDiffSE = diff;
qoe.timeDiffEDR = 1;
if ((error = rdpgfx_send_qoe_frame_acknowledge_pdu(callback, &qoe)))
if ((error = rdpgfx_send_qoe_frame_acknowledge_pdu(context, &qoe)))
WLog_Print(gfx->log, WLOG_ERROR,
"rdpgfx_send_qoe_frame_acknowledge_pdu failed with error %"PRIu32"",
error);
@ -2035,6 +2123,9 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
context->GetCacheSlotData = rdpgfx_get_cache_slot_data;
context->CapsAdvertise = rdpgfx_send_caps_advertise_pdu;
context->FrameAcknowledge = rdpgfx_send_frame_acknowledge_pdu;
context->CacheImportOffer = rdpgfx_send_cache_import_offer_pdu;
context->QoeFrameAcknowledge = rdpgfx_send_qoe_frame_acknowledge_pdu;
gfx->iface.pInterface = (void*) context;
gfx->zgfx = zgfx_context_new(FALSE);

View File

@ -1165,8 +1165,7 @@ static UINT rdpgfx_recv_cache_import_offer_pdu(RdpgfxServerContext* context,
{
cacheEntries = &(pdu.cacheEntries[index]);
Stream_Read_UINT64(s, cacheEntries->cacheKey); /* cacheKey (8 bytes) */
/* bitmapLength (4 bytes) */
Stream_Read_UINT32(s, cacheEntries->bitmapLength);
Stream_Read_UINT32(s, cacheEntries->bitmapLength); /* bitmapLength (4 bytes) */
}
if (context)

View File

@ -92,6 +92,8 @@ typedef UINT(*pcRdpgfxCapsConfirm)(RdpgfxClientContext* context,
const RDPGFX_CAPS_CONFIRM_PDU* capsConfirm);
typedef UINT(*pcRdpgfxFrameAcknowledge)(RdpgfxClientContext* context,
const RDPGFX_FRAME_ACKNOWLEDGE_PDU* frameAcknowledge);
typedef UINT(*pcRdpgfxQoeFrameAcknowledge)(RdpgfxClientContext* context,
const RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU* qoeFrameAcknowledge);
typedef UINT(*pcRdpgfxMapWindowForSurface)(RdpgfxClientContext* context, UINT16 surfaceID,
UINT64 windowID);
@ -134,6 +136,7 @@ struct _rdpgfx_client_context
pcRdpgfxCapsAdvertise CapsAdvertise;
pcRdpgfxCapsConfirm CapsConfirm;
pcRdpgfxFrameAcknowledge FrameAcknowledge;
pcRdpgfxQoeFrameAcknowledge QoeFrameAcknowledge;
/* No locking required */
pcRdpgfxUpdateSurfaces UpdateSurfaces;

View File

@ -286,6 +286,24 @@ static UINT pf_rdpgfx_frame_acknowledge(RdpgfxServerContext* context,
return client->FrameAcknowledge(client, frameAcknowledge);
}
static UINT pf_rdpgfx_qoe_frame_acknowledge(RdpgfxServerContext* context,
const RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU* qoeFrameAcknowledge)
{
proxyData* pdata = (proxyData*) context->custom;
RdpgfxClientContext* client = (RdpgfxClientContext*) pdata->pc->gfx;
WLog_DBG(TAG, __FUNCTION__);
return client->QoeFrameAcknowledge(client, qoeFrameAcknowledge);
}
static UINT pf_rdpgfx_cache_import_offer(RdpgfxServerContext* context,
const RDPGFX_CACHE_IMPORT_OFFER_PDU* cacheImportOffer)
{
proxyData* pdata = (proxyData*) context->custom;
RdpgfxClientContext* client = (RdpgfxClientContext*) pdata->pc->gfx;
WLog_DBG(TAG, __FUNCTION__);
return client->CacheImportOffer(client, cacheImportOffer);
}
void pf_rdpgfx_pipeline_init(RdpgfxClientContext* gfx, RdpgfxServerContext* server,
proxyData* pdata)
{
@ -310,10 +328,13 @@ void pf_rdpgfx_pipeline_init(RdpgfxClientContext* gfx, RdpgfxServerContext* serv
gfx->MapSurfaceToWindow = pf_rdpgfx_map_surface_to_window;
gfx->MapSurfaceToScaledOutput = pf_rdpgfx_map_surface_to_scaled_output;
gfx->MapSurfaceToScaledWindow = pf_rdpgfx_map_surface_to_scaled_window;
gfx->OnOpen = pf_rdpgfx_on_open;
gfx->OnClose = pf_rdpgfx_on_close;
gfx->CapsConfirm = pf_rdpgfx_caps_confirm;
/* Set server callbacks */
server->CapsAdvertise = pf_rdpgfx_caps_advertise;
server->FrameAcknowledge = pf_rdpgfx_frame_acknowledge;
server->CacheImportOffer = pf_rdpgfx_cache_import_offer;
server->QoeFrameAcknowledge = pf_rdpgfx_qoe_frame_acknowledge;
}