Updated EGFX support to 10.6

This commit is contained in:
Armin Novak 2019-02-27 16:36:15 +01:00
parent 69f4c4b4af
commit e8c8e7b6d0
8 changed files with 493 additions and 146 deletions

View File

@ -60,7 +60,7 @@ static UINT rdpgfx_send_caps_advertise_pdu(RDPGFX_CHANNEL_CALLBACK* callback)
RDPGFX_PLUGIN* gfx;
RDPGFX_HEADER header;
RDPGFX_CAPSET* capsSet;
RDPGFX_CAPSET capsSets[RDPGFX_NUMBER_CAPSETS];
RDPGFX_CAPSET capsSets[RDPGFX_NUMBER_CAPSETS] = { 0 };
RDPGFX_CAPS_ADVERTISE_PDU pdu;
gfx = (RDPGFX_PLUGIN*) callback->plugin;
header.flags = 0;
@ -69,6 +69,7 @@ static UINT rdpgfx_send_caps_advertise_pdu(RDPGFX_CHANNEL_CALLBACK* callback)
pdu.capsSets = (RDPGFX_CAPSET*) capsSets;
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_8;
capsSet->length = 4;
capsSet->flags = 0;
if (gfx->ThinClient)
@ -82,6 +83,7 @@ static UINT rdpgfx_send_caps_advertise_pdu(RDPGFX_CHANNEL_CALLBACK* callback)
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_81;
capsSet->length = 4;
capsSet->flags = 0;
if (gfx->ThinClient)
@ -91,30 +93,61 @@ static UINT rdpgfx_send_caps_advertise_pdu(RDPGFX_CHANNEL_CALLBACK* callback)
capsSet->flags |= RDPGFX_CAPS_FLAG_SMALL_CACHE;
#ifdef WITH_GFX_H264
if (gfx->H264)
capsSet->flags |= RDPGFX_CAPS_FLAG_AVC420_ENABLED;
#endif
if (!gfx->H264 || gfx->AVC444)
{
UINT32 caps10Flags = 0;
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_10;
capsSet->flags = 0;
capsSet->length = 4;
if (gfx->SmallCache)
capsSet->flags |= RDPGFX_CAPS_FLAG_SMALL_CACHE;
caps10Flags |= RDPGFX_CAPS_FLAG_SMALL_CACHE;
#ifdef WITH_GFX_H264
if (!gfx->AVC444)
capsSet->flags |= RDPGFX_CAPS_FLAG_AVC_DISABLED;
#else
capsSet->flags |= RDPGFX_CAPS_FLAG_AVC_DISABLED;
#endif
capsSets[pdu.capsSetCount] = *capsSet;
capsSets[pdu.capsSetCount++].version = RDPGFX_CAPVERSION_102;
capsSets[pdu.capsSetCount] = *capsSet;
capsSets[pdu.capsSetCount++].version = RDPGFX_CAPVERSION_103;
if (!gfx->AVC444)
caps10Flags |= RDPGFX_CAPS_FLAG_AVC_DISABLED;
#else
caps10Flags |= RDPGFX_CAPS_FLAG_AVC_DISABLED;
#endif
capsSet->flags = caps10Flags;
/*
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_101;
capsSet->length = 0x10;
capsSet->flags = 0;
*/
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_102;
capsSet->length = 0x4;
capsSet->flags = caps10Flags;
if (gfx->ThinClient)
caps10Flags |= RDPGFX_CAPS_FLAG_AVC_THINCLIENT;
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_103;
capsSet->length = 0x4;
capsSet->flags = caps10Flags & ~RDPGFX_CAPS_FLAG_SMALL_CACHE;
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_104;
capsSet->length = 0x4;
capsSet->flags = caps10Flags;
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_105;
capsSet->length = 0x4;
capsSet->flags = caps10Flags;
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_106;
capsSet->length = 0x4;
capsSet->flags = caps10Flags;
}
header.pduLength = RDPGFX_HEADER_SIZE + 2 + (pdu.capsSetCount * RDPGFX_CAPSET_SIZE);
@ -137,7 +170,7 @@ static UINT rdpgfx_send_caps_advertise_pdu(RDPGFX_CHANNEL_CALLBACK* callback)
{
capsSet = &(pdu.capsSets[index]);
Stream_Write_UINT32(s, capsSet->version); /* version (4 bytes) */
Stream_Write_UINT32(s, 4); /* capsDataLength (4 bytes) */
Stream_Write_UINT32(s, capsSet->length); /* capsDataLength (4 bytes) */
Stream_Write_UINT32(s, capsSet->flags); /* capsData (4 bytes) */
}
@ -161,7 +194,6 @@ static UINT rdpgfx_recv_caps_confirm_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
UINT32 capsDataLength;
RDPGFX_CAPS_CONFIRM_PDU pdu;
RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin;
pdu.capsSet = &capsSet;
if (Stream_GetRemainingLength(s) < 12)
@ -173,11 +205,9 @@ static UINT rdpgfx_recv_caps_confirm_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
Stream_Read_UINT32(s, capsSet.version); /* version (4 bytes) */
Stream_Read_UINT32(s, capsDataLength); /* capsDataLength (4 bytes) */
Stream_Read_UINT32(s, capsSet.flags); /* capsData (4 bytes) */
gfx->ConnectionCaps = capsSet;
WLog_Print(gfx->log, WLOG_DEBUG, "RecvCapsConfirmPdu: version: 0x%08"PRIX32" flags: 0x%08"PRIX32"",
capsSet.version, capsSet.flags);
capsSet.version, capsSet.flags);
return CHANNEL_RC_OK;
}
@ -193,13 +223,12 @@ static UINT rdpgfx_send_frame_acknowledge_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
wStream* s;
RDPGFX_HEADER header;
RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin;
header.flags = 0;
header.cmdId = RDPGFX_CMDID_FRAMEACKNOWLEDGE;
header.pduLength = RDPGFX_HEADER_SIZE + 12;
WLog_Print(gfx->log, WLOG_DEBUG, "SendFrameAcknowledgePdu: %"PRIu32"", pdu->frameId);
s = Stream_New(NULL, header.pduLength);
if (!s)
{
WLog_ERR(TAG, "Stream_New failed!");
@ -222,19 +251,18 @@ fail:
}
static UINT rdpgfx_send_qoe_frame_acknowledge_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
const RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU* pdu)
const RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU* pdu)
{
UINT error;
wStream* s;
RDPGFX_HEADER header;
RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin;
header.flags = 0;
header.cmdId = RDPGFX_CMDID_QOEFRAMEACKNOWLEDGE;
header.pduLength = RDPGFX_HEADER_SIZE + 12;
WLog_Print(gfx->log, WLOG_DEBUG, "SendQoeFrameAcknowledgePdu: %"PRIu32"", pdu->frameId);
s = Stream_New(NULL, header.pduLength);
if (!s)
{
WLog_ERR(TAG, "Stream_New failed!");
@ -249,7 +277,6 @@ static UINT rdpgfx_send_qoe_frame_acknowledge_pdu(RDPGFX_CHANNEL_CALLBACK* callb
Stream_Write_UINT32(s, pdu->timestamp);
Stream_Write_UINT16(s, pdu->timeDiffSE);
Stream_Write_UINT16(s, pdu->timeDiffEDR);
error = callback->channel->Write(callback->channel, (UINT32) Stream_Length(s),
Stream_Buffer(s), NULL);
fail:
@ -291,6 +318,7 @@ static UINT rdpgfx_recv_reset_graphics_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
}
pdu.monitorDefArray = (MONITOR_DEF*) calloc(pdu.monitorCount, sizeof(MONITOR_DEF));
if (!pdu.monitorDefArray)
{
WLog_Print(gfx->log, WLOG_ERROR, "calloc failed!");
@ -317,15 +345,16 @@ static UINT rdpgfx_recv_reset_graphics_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
}
Stream_Seek(s, pad); /* pad (total size is 340 bytes) */
WLog_Print(gfx->log, WLOG_DEBUG, "RecvResetGraphicsPdu: width: %"PRIu32" height: %"PRIu32" count: %"PRIu32"",
pdu.width, pdu.height, pdu.monitorCount);
WLog_Print(gfx->log, WLOG_DEBUG,
"RecvResetGraphicsPdu: width: %"PRIu32" height: %"PRIu32" count: %"PRIu32"",
pdu.width, pdu.height, pdu.monitorCount);
for (index = 0; index < pdu.monitorCount; index++)
{
monitor = &(pdu.monitorDefArray[index]);
WLog_Print(gfx->log, WLOG_DEBUG,
"RecvResetGraphicsPdu: monitor left:%"PRIi32" top:%"PRIi32" right:%"PRIi32" left:%"PRIi32" flags:0x%"PRIx32"",
monitor->left, monitor->top, monitor->right, monitor->bottom, monitor->flags);
"RecvResetGraphicsPdu: monitor left:%"PRIi32" top:%"PRIi32" right:%"PRIi32" left:%"PRIi32" flags:0x%"PRIx32"",
monitor->left, monitor->top, monitor->right, monitor->bottom, monitor->flags);
}
if (context)
@ -341,7 +370,6 @@ static UINT rdpgfx_recv_reset_graphics_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
graphicsReset.width = pdu.width;
graphicsReset.height = pdu.height;
PubSub_OnGraphicsReset(gfx->rdpcontext->pubSub, gfx->rdpcontext, &graphicsReset);
free(pdu.monitorDefArray);
return error;
}
@ -408,6 +436,7 @@ static UINT rdpgfx_recv_cache_import_reply_pdu(RDPGFX_CHANNEL_CALLBACK* callback
}
pdu.cacheSlots = (UINT16*) calloc(pdu.importedEntriesCount, sizeof(UINT16));
if (!pdu.cacheSlots)
{
WLog_Print(gfx->log, WLOG_ERROR, "calloc failed!");
@ -420,7 +449,7 @@ static UINT rdpgfx_recv_cache_import_reply_pdu(RDPGFX_CHANNEL_CALLBACK* callback
}
WLog_Print(gfx->log, WLOG_DEBUG, "RecvCacheImportReplyPdu: importedEntriesCount: %"PRIu16"",
pdu.importedEntriesCount);
pdu.importedEntriesCount);
if (context)
{
@ -458,8 +487,8 @@ static UINT rdpgfx_recv_create_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
Stream_Read_UINT16(s, pdu.height); /* height (2 bytes) */
Stream_Read_UINT8(s, pdu.pixelFormat); /* RDPGFX_PIXELFORMAT (1 byte) */
WLog_Print(gfx->log, WLOG_DEBUG,
"RecvCreateSurfacePdu: surfaceId: %"PRIu16" width: %"PRIu16" height: %"PRIu16" pixelFormat: 0x%02"PRIX8"",
pdu.surfaceId, pdu.width, pdu.height, pdu.pixelFormat);
"RecvCreateSurfacePdu: surfaceId: %"PRIu16" width: %"PRIu16" height: %"PRIu16" pixelFormat: 0x%02"PRIX8"",
pdu.surfaceId, pdu.width, pdu.height, pdu.pixelFormat);
if (context)
{
@ -527,9 +556,9 @@ static UINT rdpgfx_recv_start_frame_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
Stream_Read_UINT32(s, pdu.timestamp); /* timestamp (4 bytes) */
Stream_Read_UINT32(s, pdu.frameId); /* frameId (4 bytes) */
WLog_Print(gfx->log, WLOG_DEBUG, "RecvStartFramePdu: frameId: %"PRIu32" timestamp: 0x%08"PRIX32"",
pdu.frameId, pdu.timestamp);
pdu.frameId, pdu.timestamp);
gfx->StartDecodingTime = GetTickCountPrecise();
if (context)
{
IFCALLRET(context->StartFrame, error, context, &pdu);
@ -587,39 +616,45 @@ static UINT rdpgfx_recv_end_frame_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
if (gfx->TotalDecodedFrames == 1)
if ((error = rdpgfx_send_frame_acknowledge_pdu(callback, &ack)))
WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_send_frame_acknowledge_pdu failed with error %"PRIu32"", error);
WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_send_frame_acknowledge_pdu failed with error %"PRIu32"",
error);
}
else
{
ack.queueDepth = QUEUE_DEPTH_UNAVAILABLE;
if ((error = rdpgfx_send_frame_acknowledge_pdu(callback, &ack)))
WLog_Print(gfx->log, WLOG_DEBUG, "rdpgfx_send_frame_acknowledge_pdu failed with error %"PRIu32"", error);
WLog_Print(gfx->log, WLOG_DEBUG, "rdpgfx_send_frame_acknowledge_pdu failed with error %"PRIu32"",
error);
}
switch(gfx->ConnectionCaps.version)
switch (gfx->ConnectionCaps.version)
{
case RDPGFX_CAPVERSION_10:
case RDPGFX_CAPVERSION_102:
case RDPGFX_CAPVERSION_103:
if (gfx->SendQoeAck)
{
RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU qoe;
UINT32 diff = (GetTickCountPrecise() - gfx->StartDecodingTime);
case RDPGFX_CAPVERSION_10:
case RDPGFX_CAPVERSION_102:
case RDPGFX_CAPVERSION_103:
if (gfx->SendQoeAck)
{
RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU qoe;
UINT32 diff = (GetTickCountPrecise() - gfx->StartDecodingTime);
if (diff > 65000)
diff = 0;
if (diff > 65000)
diff = 0;
qoe.frameId = pdu.frameId;
qoe.timestamp = gfx->StartDecodingTime;
qoe.timeDiffSE = diff;
qoe.timeDiffEDR = 1;
if ((error = rdpgfx_send_qoe_frame_acknowledge_pdu(callback, &qoe)))
WLog_Print(gfx->log, WLOG_DEBUG, "rdpgfx_send_frame_acknowledge_pdu failed with error %"PRIu32"", error);
}
break;
default:
break;
qoe.frameId = pdu.frameId;
qoe.timestamp = gfx->StartDecodingTime;
qoe.timeDiffSE = diff;
qoe.timeDiffEDR = 1;
if ((error = rdpgfx_send_qoe_frame_acknowledge_pdu(callback, &qoe)))
WLog_Print(gfx->log, WLOG_DEBUG, "rdpgfx_send_frame_acknowledge_pdu failed with error %"PRIu32"",
error);
}
break;
default:
break;
}
return error;
@ -665,13 +700,13 @@ static UINT rdpgfx_recv_wire_to_surface_1_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
pdu.bitmapData = Stream_Pointer(s);
Stream_Seek(s, pdu.bitmapDataLength);
WLog_Print(gfx->log, WLOG_DEBUG,
"RecvWireToSurface1Pdu: surfaceId: %"PRIu16" codecId: %s (0x%04"PRIX16") pixelFormat: 0x%02"PRIX8" "
"destRect: left: %"PRIu16" top: %"PRIu16" right: %"PRIu16" bottom: %"PRIu16" bitmapDataLength: %"PRIu32"",
pdu.surfaceId, rdpgfx_get_codec_id_string(pdu.codecId),
pdu.codecId, pdu.pixelFormat,
pdu.destRect.left, pdu.destRect.top,
pdu.destRect.right, pdu.destRect.bottom,
pdu.bitmapDataLength);
"RecvWireToSurface1Pdu: surfaceId: %"PRIu16" codecId: %s (0x%04"PRIX16") pixelFormat: 0x%02"PRIX8" "
"destRect: left: %"PRIu16" top: %"PRIu16" right: %"PRIu16" bottom: %"PRIu16" bitmapDataLength: %"PRIu32"",
pdu.surfaceId, rdpgfx_get_codec_id_string(pdu.codecId),
pdu.codecId, pdu.pixelFormat,
pdu.destRect.left, pdu.destRect.top,
pdu.destRect.right, pdu.destRect.bottom,
pdu.bitmapDataLength);
cmd.surfaceId = pdu.surfaceId;
cmd.codecId = pdu.codecId;
cmd.contextId = 0;
@ -733,10 +768,11 @@ static UINT rdpgfx_recv_wire_to_surface_2_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
Stream_Read_UINT32(s, pdu.bitmapDataLength); /* bitmapDataLength (4 bytes) */
pdu.bitmapData = Stream_Pointer(s);
Stream_Seek(s, pdu.bitmapDataLength);
WLog_Print(gfx->log, WLOG_DEBUG, "RecvWireToSurface2Pdu: surfaceId: %"PRIu16" codecId: %s (0x%04"PRIX16") "
"codecContextId: %"PRIu32" pixelFormat: 0x%02"PRIX8" bitmapDataLength: %"PRIu32"",
pdu.surfaceId, rdpgfx_get_codec_id_string(pdu.codecId), pdu.codecId,
pdu.codecContextId, pdu.pixelFormat, pdu.bitmapDataLength);
WLog_Print(gfx->log, WLOG_DEBUG,
"RecvWireToSurface2Pdu: surfaceId: %"PRIu16" codecId: %s (0x%04"PRIX16") "
"codecContextId: %"PRIu32" pixelFormat: 0x%02"PRIX8" bitmapDataLength: %"PRIu32"",
pdu.surfaceId, rdpgfx_get_codec_id_string(pdu.codecId), pdu.codecId,
pdu.codecContextId, pdu.pixelFormat, pdu.bitmapDataLength);
cmd.surfaceId = pdu.surfaceId;
cmd.codecId = pdu.codecId;
cmd.contextId = pdu.codecContextId;
@ -783,15 +819,17 @@ static UINT rdpgfx_recv_delete_encoding_context_pdu(RDPGFX_CHANNEL_CALLBACK*
Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */
Stream_Read_UINT32(s, pdu.codecContextId); /* codecContextId (4 bytes) */
WLog_Print(gfx->log, WLOG_DEBUG, "RecvDeleteEncodingContextPdu: surfaceId: %"PRIu16" codecContextId: %"PRIu32"",
pdu.surfaceId, pdu.codecContextId);
WLog_Print(gfx->log, WLOG_DEBUG,
"RecvDeleteEncodingContextPdu: surfaceId: %"PRIu16" codecContextId: %"PRIu32"",
pdu.surfaceId, pdu.codecContextId);
if (context)
{
IFCALLRET(context->DeleteEncodingContext, error, context, &pdu);
if (error)
WLog_Print(gfx->log, WLOG_ERROR, "context->DeleteEncodingContext failed with error %"PRIu32"", error);
WLog_Print(gfx->log, WLOG_ERROR, "context->DeleteEncodingContext failed with error %"PRIu32"",
error);
}
return error;
@ -834,6 +872,7 @@ static UINT rdpgfx_recv_solid_fill_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStrea
}
pdu.fillRects = (RECTANGLE_16*) calloc(pdu.fillRectCount, sizeof(RECTANGLE_16));
if (!pdu.fillRects)
{
WLog_Print(gfx->log, WLOG_ERROR, "calloc failed!");
@ -853,7 +892,7 @@ static UINT rdpgfx_recv_solid_fill_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStrea
}
WLog_Print(gfx->log, WLOG_DEBUG, "RecvSolidFillPdu: surfaceId: %"PRIu16" fillRectCount: %"PRIu16"",
pdu.surfaceId, pdu.fillRectCount);
pdu.surfaceId, pdu.fillRectCount);
if (context)
{
@ -906,6 +945,7 @@ static UINT rdpgfx_recv_surface_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK*
}
pdu.destPts = (RDPGFX_POINT16*) calloc(pdu.destPtsCount, sizeof(RDPGFX_POINT16));
if (!pdu.destPts)
{
WLog_Print(gfx->log, WLOG_ERROR, "calloc failed!");
@ -924,11 +964,12 @@ static UINT rdpgfx_recv_surface_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK*
}
}
WLog_Print(gfx->log, WLOG_DEBUG, "RecvSurfaceToSurfacePdu: surfaceIdSrc: %"PRIu16" surfaceIdDest: %"PRIu16" "
"left: %"PRIu16" top: %"PRIu16" right: %"PRIu16" bottom: %"PRIu16" destPtsCount: %"PRIu16"",
pdu.surfaceIdSrc, pdu.surfaceIdDest,
pdu.rectSrc.left, pdu.rectSrc.top, pdu.rectSrc.right, pdu.rectSrc.bottom,
pdu.destPtsCount);
WLog_Print(gfx->log, WLOG_DEBUG,
"RecvSurfaceToSurfacePdu: surfaceIdSrc: %"PRIu16" surfaceIdDest: %"PRIu16" "
"left: %"PRIu16" top: %"PRIu16" right: %"PRIu16" bottom: %"PRIu16" destPtsCount: %"PRIu16"",
pdu.surfaceIdSrc, pdu.surfaceIdDest,
pdu.rectSrc.left, pdu.rectSrc.top, pdu.rectSrc.right, pdu.rectSrc.bottom,
pdu.destPtsCount);
if (context)
{
@ -972,11 +1013,11 @@ static UINT rdpgfx_recv_surface_to_cache_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
}
WLog_Print(gfx->log, WLOG_DEBUG,
"RecvSurfaceToCachePdu: surfaceId: %"PRIu16" cacheKey: 0x%016"PRIX64" cacheSlot: %"PRIu16" "
"left: %"PRIu16" top: %"PRIu16" right: %"PRIu16" bottom: %"PRIu16"",
pdu.surfaceId, pdu.cacheKey, pdu.cacheSlot,
pdu.rectSrc.left, pdu.rectSrc.top,
pdu.rectSrc.right, pdu.rectSrc.bottom);
"RecvSurfaceToCachePdu: surfaceId: %"PRIu16" cacheKey: 0x%016"PRIX64" cacheSlot: %"PRIu16" "
"left: %"PRIu16" top: %"PRIu16" right: %"PRIu16" bottom: %"PRIu16"",
pdu.surfaceId, pdu.cacheKey, pdu.cacheSlot,
pdu.rectSrc.left, pdu.rectSrc.top,
pdu.rectSrc.right, pdu.rectSrc.bottom);
if (context)
{
@ -1021,6 +1062,7 @@ static UINT rdpgfx_recv_cache_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
}
pdu.destPts = (RDPGFX_POINT16*) calloc(pdu.destPtsCount, sizeof(RDPGFX_POINT16));
if (!pdu.destPts)
{
WLog_Print(gfx->log, WLOG_ERROR, "calloc failed!");
@ -1040,8 +1082,8 @@ static UINT rdpgfx_recv_cache_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
}
WLog_Print(gfx->log, WLOG_DEBUG,
"RdpGfxRecvCacheToSurfacePdu: cacheSlot: %"PRIu16" surfaceId: %"PRIu16" destPtsCount: %"PRIu16"",
pdu.cacheSlot, pdu.surfaceId, pdu.destPtsCount);
"RdpGfxRecvCacheToSurfacePdu: cacheSlot: %"PRIu16" surfaceId: %"PRIu16" destPtsCount: %"PRIu16"",
pdu.cacheSlot, pdu.surfaceId, pdu.destPtsCount);
if (context)
{
@ -1079,8 +1121,8 @@ static UINT rdpgfx_recv_map_surface_to_output_pdu(RDPGFX_CHANNEL_CALLBACK*
Stream_Read_UINT32(s, pdu.outputOriginX); /* outputOriginX (4 bytes) */
Stream_Read_UINT32(s, pdu.outputOriginY); /* outputOriginY (4 bytes) */
WLog_Print(gfx->log, WLOG_DEBUG,
"RecvMapSurfaceToOutputPdu: surfaceId: %"PRIu16" outputOriginX: %"PRIu32" outputOriginY: %"PRIu32"",
pdu.surfaceId, pdu.outputOriginX, pdu.outputOriginY);
"RecvMapSurfaceToOutputPdu: surfaceId: %"PRIu16" outputOriginX: %"PRIu32" outputOriginY: %"PRIu32"",
pdu.surfaceId, pdu.outputOriginX, pdu.outputOriginY);
if (context)
{
@ -1093,6 +1135,42 @@ static UINT rdpgfx_recv_map_surface_to_output_pdu(RDPGFX_CHANNEL_CALLBACK*
return error;
}
static UINT rdpgfx_recv_map_surface_to_scaled_output_pdu(RDPGFX_CHANNEL_CALLBACK*
callback, wStream* s)
{
RDPGFX_MAP_SURFACE_TO_SCALED_OUTPUT_PDU pdu;
RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin;
RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface;
UINT error = CHANNEL_RC_OK;
if (Stream_GetRemainingLength(s) < 12)
{
WLog_Print(gfx->log, WLOG_ERROR, "not enough data!");
return ERROR_INVALID_DATA;
}
Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */
Stream_Read_UINT16(s, pdu.reserved); /* reserved (2 bytes) */
Stream_Read_UINT32(s, pdu.outputOriginX); /* outputOriginX (4 bytes) */
Stream_Read_UINT32(s, pdu.outputOriginY); /* outputOriginY (4 bytes) */
Stream_Read_UINT32(s, pdu.targetX);
Stream_Read_UINT32(s, pdu.targetY);
WLog_Print(gfx->log, WLOG_DEBUG,
"RecvMapSurfaceToOutputPdu: surfaceId: %"PRIu16" outputOriginX: %"PRIu32" outputOriginY: %"PRIu32" targetX: %"PRIu32" targetY: %"PRIu32,
pdu.surfaceId, pdu.outputOriginX, pdu.outputOriginY, pdu.targetX, pdu.targetY);
if (context)
{
IFCALLRET(context->MapSurfaceToScaledOutput, error, context, &pdu);
if (error)
WLog_Print(gfx->log, WLOG_ERROR, "context->MapSurfaceToScaledOutput failed with error %"PRIu32"",
error);
}
return error;
}
/**
* Function description
*
@ -1117,8 +1195,8 @@ static UINT rdpgfx_recv_map_surface_to_window_pdu(RDPGFX_CHANNEL_CALLBACK* callb
Stream_Read_UINT32(s, pdu.mappedWidth); /* mappedWidth (4 bytes) */
Stream_Read_UINT32(s, pdu.mappedHeight); /* mappedHeight (4 bytes) */
WLog_Print(gfx->log, WLOG_DEBUG,
"RecvMapSurfaceToWindowPdu: surfaceId: %"PRIu16" windowId: 0x%016"PRIX64" mappedWidth: %"PRIu32" mappedHeight: %"PRIu32"",
pdu.surfaceId, pdu.windowId, pdu.mappedWidth, pdu.mappedHeight);
"RecvMapSurfaceToWindowPdu: surfaceId: %"PRIu16" windowId: 0x%016"PRIX64" mappedWidth: %"PRIu32" mappedHeight: %"PRIu32"",
pdu.surfaceId, pdu.windowId, pdu.mappedWidth, pdu.mappedHeight);
if (context && context->MapSurfaceToWindow)
{
@ -1131,6 +1209,43 @@ static UINT rdpgfx_recv_map_surface_to_window_pdu(RDPGFX_CHANNEL_CALLBACK* callb
return error;
}
static UINT rdpgfx_recv_map_surface_to_scaled_window_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
wStream* s)
{
RDPGFX_MAP_SURFACE_TO_SCALED_WINDOW_PDU pdu;
RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin;
RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface;
UINT error = CHANNEL_RC_OK;
if (Stream_GetRemainingLength(s) < 18)
{
WLog_Print(gfx->log, WLOG_ERROR, "not enough data!");
return ERROR_INVALID_DATA;
}
Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */
Stream_Read_UINT64(s, pdu.windowId); /* windowId (8 bytes) */
Stream_Read_UINT32(s, pdu.mappedWidth); /* mappedWidth (4 bytes) */
Stream_Read_UINT32(s, pdu.mappedHeight); /* mappedHeight (4 bytes) */
Stream_Read_UINT32(s, pdu.targetWidth);
Stream_Read_UINT32(s, pdu.targetHeight);
WLog_Print(gfx->log, WLOG_DEBUG,
"RecvMapSurfaceToWindowPdu: surfaceId: %"PRIu16" windowId: 0x%016"PRIX64" mappedWidth: %"PRIu32" mappedHeight: %"PRIu32"",
pdu.surfaceId, pdu.windowId, pdu.mappedWidth, pdu.mappedHeight);
if (context && context->MapSurfaceToScaledWindow)
{
IFCALLRET(context->MapSurfaceToScaledWindow, error, context, &pdu);
if (error)
WLog_Print(gfx->log, WLOG_ERROR, "context->MapSurfaceToScaledWindow failed with error %"PRIu32"",
error);
}
return error;
}
/**
* Function description
*
@ -1142,7 +1257,6 @@ static UINT rdpgfx_recv_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s)
RDPGFX_HEADER header;
UINT error;
RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin;
beg = Stream_GetPosition(s);
if ((error = rdpgfx_read_header(s, &header)))
@ -1151,30 +1265,32 @@ static UINT rdpgfx_recv_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s)
return error;
}
WLog_Print(gfx->log, WLOG_DEBUG, "cmdId: %s (0x%04"PRIX16") flags: 0x%04"PRIX16" pduLength: %"PRIu32"",
rdpgfx_get_cmd_id_string(header.cmdId), header.cmdId, header.flags,
header.pduLength);
WLog_Print(gfx->log, WLOG_DEBUG,
"cmdId: %s (0x%04"PRIX16") flags: 0x%04"PRIX16" pduLength: %"PRIu32"",
rdpgfx_get_cmd_id_string(header.cmdId), header.cmdId, header.flags,
header.pduLength);
switch (header.cmdId)
{
case RDPGFX_CMDID_WIRETOSURFACE_1:
if ((error = rdpgfx_recv_wire_to_surface_1_pdu(callback, s)))
WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_wire_to_surface_1_pdu failed with error %"PRIu32"!",
error);
error);
break;
case RDPGFX_CMDID_WIRETOSURFACE_2:
if ((error = rdpgfx_recv_wire_to_surface_2_pdu(callback, s)))
WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_wire_to_surface_2_pdu failed with error %"PRIu32"!",
error);
error);
break;
case RDPGFX_CMDID_DELETEENCODINGCONTEXT:
if ((error = rdpgfx_recv_delete_encoding_context_pdu(callback, s)))
WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_delete_encoding_context_pdu failed with error %"PRIu32"!",
error);
WLog_Print(gfx->log, WLOG_ERROR,
"rdpgfx_recv_delete_encoding_context_pdu failed with error %"PRIu32"!",
error);
break;
@ -1187,38 +1303,42 @@ static UINT rdpgfx_recv_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s)
case RDPGFX_CMDID_SURFACETOSURFACE:
if ((error = rdpgfx_recv_surface_to_surface_pdu(callback, s)))
WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_surface_to_surface_pdu failed with error %"PRIu32"!",
error);
error);
break;
case RDPGFX_CMDID_SURFACETOCACHE:
if ((error = rdpgfx_recv_surface_to_cache_pdu(callback, s)))
WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_surface_to_cache_pdu failed with error %"PRIu32"!", error);
WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_surface_to_cache_pdu failed with error %"PRIu32"!",
error);
break;
case RDPGFX_CMDID_CACHETOSURFACE:
if ((error = rdpgfx_recv_cache_to_surface_pdu(callback, s)))
WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_cache_to_surface_pdu failed with error %"PRIu32"!", error);
WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_cache_to_surface_pdu failed with error %"PRIu32"!",
error);
break;
case RDPGFX_CMDID_EVICTCACHEENTRY:
if ((error = rdpgfx_recv_evict_cache_entry_pdu(callback, s)))
WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_evict_cache_entry_pdu failed with error %"PRIu32"!",
error);
error);
break;
case RDPGFX_CMDID_CREATESURFACE:
if ((error = rdpgfx_recv_create_surface_pdu(callback, s)))
WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_create_surface_pdu failed with error %"PRIu32"!", error);
WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_create_surface_pdu failed with error %"PRIu32"!",
error);
break;
case RDPGFX_CMDID_DELETESURFACE:
if ((error = rdpgfx_recv_delete_surface_pdu(callback, s)))
WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_delete_surface_pdu failed with error %"PRIu32"!", error);
WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_delete_surface_pdu failed with error %"PRIu32"!",
error);
break;
@ -1236,34 +1356,54 @@ static UINT rdpgfx_recv_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s)
case RDPGFX_CMDID_RESETGRAPHICS:
if ((error = rdpgfx_recv_reset_graphics_pdu(callback, s)))
WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_reset_graphics_pdu failed with error %"PRIu32"!", error);
WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_reset_graphics_pdu failed with error %"PRIu32"!",
error);
break;
case RDPGFX_CMDID_MAPSURFACETOOUTPUT:
if ((error = rdpgfx_recv_map_surface_to_output_pdu(callback, s)))
WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_map_surface_to_output_pdu failed with error %"PRIu32"!",
error);
WLog_Print(gfx->log, WLOG_ERROR,
"rdpgfx_recv_map_surface_to_output_pdu failed with error %"PRIu32"!",
error);
break;
case RDPGFX_CMDID_CACHEIMPORTREPLY:
if ((error = rdpgfx_recv_cache_import_reply_pdu(callback, s)))
WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_cache_import_reply_pdu failed with error %"PRIu32"!",
error);
error);
break;
case RDPGFX_CMDID_CAPSCONFIRM:
if ((error = rdpgfx_recv_caps_confirm_pdu(callback, s)))
WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_caps_confirm_pdu failed with error %"PRIu32"!", error);
WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_caps_confirm_pdu failed with error %"PRIu32"!",
error);
break;
case RDPGFX_CMDID_MAPSURFACETOWINDOW:
if ((error = rdpgfx_recv_map_surface_to_window_pdu(callback, s)))
WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_map_surface_to_window_pdu failed with error %"PRIu32"!",
error);
WLog_Print(gfx->log, WLOG_ERROR,
"rdpgfx_recv_map_surface_to_window_pdu failed with error %"PRIu32"!",
error);
break;
case RDPGFX_CMDID_MAPSURFACETOSCALEDWINDOW:
if ((error = rdpgfx_recv_map_surface_to_scaled_window_pdu(callback, s)))
WLog_Print(gfx->log, WLOG_ERROR,
"rdpgfx_recv_map_surface_to_scaled_window_pdu failed with error %"PRIu32"!",
error);
break;
case RDPGFX_CMDID_MAPSURFACETOSCALEDOUTPUT:
if ((error = rdpgfx_recv_map_surface_to_scaled_output_pdu(callback, s)))
WLog_Print(gfx->log, WLOG_ERROR,
"rdpgfx_recv_map_surface_to_scaled_output_pdu failed with error %"PRIu32"!",
error);
break;
@ -1275,7 +1415,7 @@ static UINT rdpgfx_recv_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s)
if (error)
{
WLog_Print(gfx->log, WLOG_ERROR, "Error while parsing GFX cmdId: %s (0x%04"PRIX16")",
rdpgfx_get_cmd_id_string(header.cmdId), header.cmdId);
rdpgfx_get_cmd_id_string(header.cmdId), header.cmdId);
return error;
}
@ -1284,7 +1424,7 @@ static UINT rdpgfx_recv_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s)
if (end != (beg + header.pduLength))
{
WLog_Print(gfx->log, WLOG_ERROR, "Unexpected gfx pdu end: Actual: %d, Expected: %"PRIu32"",
end, (beg + header.pduLength));
end, (beg + header.pduLength));
Stream_SetPosition(s, (beg + header.pduLength));
}
@ -1307,7 +1447,7 @@ static UINT rdpgfx_on_data_received(IWTSVirtualChannelCallback*
RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin;
UINT error = CHANNEL_RC_OK;
status = zgfx_decompress(gfx->zgfx, Stream_Pointer(data), Stream_GetRemainingLength(data),
&pDstData, &DstSize, 0);
&pDstData, &DstSize, 0);
if (status < 0)
{
@ -1316,6 +1456,7 @@ static UINT rdpgfx_on_data_received(IWTSVirtualChannelCallback*
}
s = Stream_New(pDstData, DstSize);
if (!s)
{
WLog_Print(gfx->log, WLOG_ERROR, "calloc failed!");
@ -1360,7 +1501,6 @@ static UINT rdpgfx_on_close(IWTSVirtualChannelCallback* pChannelCallback)
RDPGFX_CHANNEL_CALLBACK* callback = (RDPGFX_CHANNEL_CALLBACK*) pChannelCallback;
RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin;
RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface;
WLog_Print(gfx->log, WLOG_DEBUG, "OnClose");
free(callback);
gfx->UnacknowledgedFrames = 0;
@ -1421,8 +1561,8 @@ static UINT rdpgfx_on_new_channel_connection(IWTSListenerCallback*
{
RDPGFX_CHANNEL_CALLBACK* callback;
RDPGFX_LISTENER_CALLBACK* listener_callback = (RDPGFX_LISTENER_CALLBACK*)pListenerCallback;
callback = (RDPGFX_CHANNEL_CALLBACK*) calloc(1, sizeof(RDPGFX_CHANNEL_CALLBACK));
if (!callback)
{
WLog_ERR(TAG, "calloc failed!");
@ -1450,8 +1590,8 @@ static UINT rdpgfx_plugin_initialize(IWTSPlugin* pPlugin,
{
UINT error;
RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) pPlugin;
gfx->listener_callback = (RDPGFX_LISTENER_CALLBACK*) calloc(1, sizeof(RDPGFX_LISTENER_CALLBACK));
if (!gfx->listener_callback)
{
WLog_Print(gfx->log, WLOG_ERROR, "calloc failed!");
@ -1634,7 +1774,7 @@ static UINT rdpgfx_set_cache_slot_data(RdpgfxClientContext* context,
if (cacheSlot >= gfx->MaxCacheSlot)
{
WLog_ERR(TAG, "%s: invalid cache slot %"PRIu16" maxAllowed=%"PRIu16"", __FUNCTION__,
cacheSlot, gfx->MaxCacheSlot);
cacheSlot, gfx->MaxCacheSlot);
return ERROR_INVALID_INDEX;
}
@ -1650,7 +1790,7 @@ static void* rdpgfx_get_cache_slot_data(RdpgfxClientContext* context, UINT16 cac
if (cacheSlot >= gfx->MaxCacheSlot)
{
WLog_ERR(TAG, "%s: invalid cache slot %"PRIu16" maxAllowed=%"PRIu16"", __FUNCTION__,
cacheSlot, gfx->MaxCacheSlot);
cacheSlot, gfx->MaxCacheSlot);
return NULL;
}
@ -1687,6 +1827,7 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
}
gfx->log = WLog_Get(TAG);
if (!gfx->log)
{
free(gfx);
@ -1699,9 +1840,9 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
gfx->iface.Connected = NULL;
gfx->iface.Disconnected = NULL;
gfx->iface.Terminated = rdpgfx_plugin_terminated;
gfx->rdpcontext = ((freerdp *)gfx->settings->instance)->context;
gfx->rdpcontext = ((freerdp*)gfx->settings->instance)->context;
gfx->SurfaceTable = HashTable_New(TRUE);
if (!gfx->SurfaceTable)
{
free(gfx);
@ -1721,8 +1862,8 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
gfx->SmallCache = TRUE;
gfx->MaxCacheSlot = gfx->SmallCache ? 4096 : 25600;
context = (RdpgfxClientContext*)calloc(1, sizeof(RdpgfxClientContext));
context = (RdpgfxClientContext *)calloc(1, sizeof(RdpgfxClientContext));
if (!context)
{
free(gfx);

View File

@ -55,12 +55,14 @@ static const char* RDPGFX_CMDID_STRINGS[] =
"RDPGFX_CMDID_CAPSCONFIRM",
"RDPGFX_CMDID_UNUSED_0014",
"RDPGFX_CMDID_MAPSURFACETOWINDOW",
"RDPGFX_CMDID_QOEFRAMEACKNOWLEDGE"
"RDPGFX_CMDID_QOEFRAMEACKNOWLEDGE",
"RDPGFX_CMDID_MAPSURFACETOSCALEDOUTPUT",
"RDPGFX_CMDID_MAPSURFACETOSCALEDWINDOW"
};
const char* rdpgfx_get_cmd_id_string(UINT16 cmdId)
{
if (cmdId <= RDPGFX_CMDID_MAPSURFACETOWINDOW)
if (cmdId <= RDPGFX_CMDID_MAPSURFACETOSCALEDWINDOW)
return RDPGFX_CMDID_STRINGS[cmdId];
else
return "RDPGFX_CMDID_UNKNOWN";

View File

@ -1053,6 +1053,27 @@ static UINT rdpgfx_send_map_surface_to_window_pdu(RdpgfxServerContext* context,
return rdpgfx_server_single_packet_send(context, s);
}
static UINT rdpgfx_send_map_surface_to_scaled_window_pdu(RdpgfxServerContext* context,
RDPGFX_MAP_SURFACE_TO_SCALED_WINDOW_PDU* pdu)
{
wStream* s = rdpgfx_server_single_packet_new(
RDPGFX_CMDID_MAPSURFACETOWINDOW, 18);
if (!s)
{
WLog_ERR(TAG, "rdpgfx_server_single_packet_new failed!");
return CHANNEL_RC_NO_MEMORY;
}
Stream_Write_UINT16(s, pdu->surfaceId); /* surfaceId (2 bytes) */
Stream_Write_UINT64(s, pdu->windowId); /* windowId (8 bytes) */
Stream_Write_UINT32(s, pdu->mappedWidth); /* mappedWidth (4 bytes) */
Stream_Write_UINT32(s, pdu->mappedHeight); /* mappedHeight (4 bytes) */
Stream_Write_UINT32(s, pdu->targetWidth);
Stream_Write_UINT32(s, pdu->targetHeight);
return rdpgfx_server_single_packet_send(context, s);
}
/**
* Function description
*
@ -1251,6 +1272,27 @@ static UINT rdpgfx_recv_qoe_frame_acknowledge_pdu(RdpgfxServerContext* context,
return error;
}
static UINT rdpgfx_send_map_surface_to_scaled_output_pdu(RdpgfxServerContext* context,
RDPGFX_MAP_SURFACE_TO_SCALED_OUTPUT_PDU* pdu)
{
wStream* s = rdpgfx_server_single_packet_new(
RDPGFX_CMDID_MAPSURFACETOSCALEDOUTPUT, 12);
if (!s)
{
WLog_ERR(TAG, "rdpgfx_server_single_packet_new failed!");
return CHANNEL_RC_NO_MEMORY;
}
Stream_Write_UINT16(s, pdu->surfaceId); /* surfaceId (2 bytes) */
Stream_Write_UINT16(s, 0); /* reserved (2 bytes). Must be 0 */
Stream_Write_UINT32(s, pdu->outputOriginX); /* outputOriginX (4 bytes) */
Stream_Write_UINT32(s, pdu->outputOriginY); /* outputOriginY (4 bytes) */
Stream_Write_UINT32(s, pdu->targetX);
Stream_Write_UINT32(s, pdu->targetY);
return rdpgfx_server_single_packet_send(context, s);
}
/**
* Function description
*
@ -1533,6 +1575,8 @@ RdpgfxServerContext* rdpgfx_server_context_new(HANDLE vcm)
context->EvictCacheEntry = rdpgfx_send_evict_cache_entry_pdu;
context->MapSurfaceToOutput = rdpgfx_send_map_surface_to_output_pdu;
context->MapSurfaceToWindow = rdpgfx_send_map_surface_to_window_pdu;
context->MapSurfaceToScaledOutput = rdpgfx_send_map_surface_to_scaled_output_pdu;
context->MapSurfaceToScaledWindow = rdpgfx_send_map_surface_to_scaled_window_pdu;
context->CapsAdvertise = NULL;
context->CapsConfirm = rdpgfx_send_caps_confirm_pdu;
context->FrameAcknowledge = NULL;

View File

@ -74,6 +74,8 @@ typedef BYTE RDPGFX_PIXELFORMAT;
#define RDPGFX_CMDID_UNUSED_0014 0x0014
#define RDPGFX_CMDID_MAPSURFACETOWINDOW 0x0015
#define RDPGFX_CMDID_QOEFRAMEACKNOWLEDGE 0x0016
#define RDPGFX_CMDID_MAPSURFACETOSCALEDOUTPUT 0x0017
#define RDPGFX_CMDID_MAPSURFACETOSCALEDWINDOW 0x0018
#define RDPGFX_HEADER_SIZE 8
@ -92,15 +94,20 @@ typedef struct _RDPGFX_HEADER RDPGFX_HEADER;
#define RDPGFX_CAPVERSION_8 0x00080004 /** [MS-RDPEGFX] 2.2.3.1 */
#define RDPGFX_CAPVERSION_81 0x00080105 /** [MS-RDPEGFX] 2.2.3.2 */
#define RDPGFX_CAPVERSION_10 0x000A0002 /** [MS-RDPEGFX] 2.2.3.3 */
#define RDPGFX_CAPVERSION_102 0x000A0200 /** [MS-RDPEGFX] 2.2.3.4 */
#define RDPGFX_CAPVERSION_103 0x000A0301 /** [MS-RDPEGFX] 2.2.3.5 */
#define RDPGFX_CAPVERSION_101 0x000A0100 /** [MS-RDPEGFX] 2.2.3.4 */
#define RDPGFX_CAPVERSION_102 0x000A0200 /** [MS-RDPEGFX] 2.2.3.5 */
#define RDPGFX_CAPVERSION_103 0x000A0301 /** [MS-RDPEGFX] 2.2.3.6 */
#define RDPGFX_CAPVERSION_104 0x000A0400 /** [MS-RDPEGFX] 2.2.3.7 */
#define RDPGFX_CAPVERSION_105 0x000A0502 /** [MS-RDPEGFX] 2.2.3.8 */
#define RDPGFX_CAPVERSION_106 0x000A0601 /** [MS-RDPEGFX] 2.2.3.9 */
#define RDPGFX_NUMBER_CAPSETS 5
#define RDPGFX_NUMBER_CAPSETS 9
#define RDPGFX_CAPSET_SIZE 12
struct _RDPGFX_CAPSET
{
UINT32 version;
UINT32 length;
UINT32 flags;
};
typedef struct _RDPGFX_CAPSET RDPGFX_CAPSET;
@ -109,6 +116,7 @@ typedef struct _RDPGFX_CAPSET RDPGFX_CAPSET;
#define RDPGFX_CAPS_FLAG_SMALL_CACHE 0x00000002U /* 8.0+ */
#define RDPGFX_CAPS_FLAG_AVC420_ENABLED 0x00000010U /* 8.1+ */
#define RDPGFX_CAPS_FLAG_AVC_DISABLED 0x00000020U /* 10.0+ */
#define RDPGFX_CAPS_FLAG_AVC_THINCLIENT 0x00000040U /* 10.3+ */
struct _RDPGFX_CAPSET_VERSION8
{
@ -200,7 +208,7 @@ struct _RDPGFX_DELETE_ENCODING_CONTEXT_PDU
UINT32 codecContextId;
};
typedef struct _RDPGFX_DELETE_ENCODING_CONTEXT_PDU
RDPGFX_DELETE_ENCODING_CONTEXT_PDU;
RDPGFX_DELETE_ENCODING_CONTEXT_PDU;
struct _RDPGFX_SOLID_FILL_PDU
{
@ -305,7 +313,19 @@ struct _RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU
UINT32 outputOriginY;
};
typedef struct _RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU
RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU;
RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU;
struct _RDPGFX_MAP_SURFACE_TO_SCALED_OUTPUT_PDU
{
UINT16 surfaceId;
UINT16 reserved;
UINT32 outputOriginX;
UINT32 outputOriginY;
UINT32 targetX;
UINT32 targetY;
};
typedef struct _RDPGFX_MAP_SURFACE_TO_SCALED_OUTPUT_PDU
RDPGFX_MAP_SURFACE_TO_SCALED_OUTPUT_PDU;
struct _RDPGFX_CACHE_ENTRY_METADATA
{
@ -349,7 +369,19 @@ struct _RDPGFX_MAP_SURFACE_TO_WINDOW_PDU
UINT32 mappedHeight;
};
typedef struct _RDPGFX_MAP_SURFACE_TO_WINDOW_PDU
RDPGFX_MAP_SURFACE_TO_WINDOW_PDU;
RDPGFX_MAP_SURFACE_TO_WINDOW_PDU;
struct _RDPGFX_MAP_SURFACE_TO_SCALED_WINDOW_PDU
{
UINT16 surfaceId;
UINT64 windowId;
UINT32 mappedWidth;
UINT32 mappedHeight;
UINT32 targetWidth;
UINT32 targetHeight;
};
typedef struct _RDPGFX_MAP_SURFACE_TO_SCALED_WINDOW_PDU
RDPGFX_MAP_SURFACE_TO_SCALED_WINDOW_PDU;
/* H264 */
@ -396,7 +428,7 @@ struct _RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU
UINT16 timeDiffEDR;
};
typedef struct _RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU
RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU;
RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU;
#endif /* FREERDP_CHANNEL_RDPGFX_H */

View File

@ -61,9 +61,12 @@ typedef UINT(*pcRdpgfxEvictCacheEntry)(RdpgfxClientContext* context,
const RDPGFX_EVICT_CACHE_ENTRY_PDU* evictCacheEntry);
typedef UINT(*pcRdpgfxMapSurfaceToOutput)(RdpgfxClientContext* context,
const RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU* surfaceToOutput);
typedef UINT(*pcRdpgfxMapSurfaceToScaledOutput)(RdpgfxClientContext* context,
const RDPGFX_MAP_SURFACE_TO_SCALED_OUTPUT_PDU* surfaceToOutput);
typedef UINT(*pcRdpgfxMapSurfaceToWindow)(RdpgfxClientContext* context,
const RDPGFX_MAP_SURFACE_TO_WINDOW_PDU* surfaceToWindow);
typedef UINT(*pcRdpgfxMapSurfaceToScaledWindow)(RdpgfxClientContext* context,
const RDPGFX_MAP_SURFACE_TO_SCALED_WINDOW_PDU* surfaceToWindow);
typedef UINT(*pcRdpgfxSetSurfaceData)(RdpgfxClientContext* context,
UINT16 surfaceId, void* pData);
typedef void* (*pcRdpgfxGetSurfaceData)(RdpgfxClientContext* context,
@ -101,7 +104,9 @@ struct _rdpgfx_client_context
pcRdpgfxCacheImportReply CacheImportReply;
pcRdpgfxEvictCacheEntry EvictCacheEntry;
pcRdpgfxMapSurfaceToOutput MapSurfaceToOutput;
pcRdpgfxMapSurfaceToScaledOutput MapSurfaceToScaledOutput;
pcRdpgfxMapSurfaceToWindow MapSurfaceToWindow;
pcRdpgfxMapSurfaceToScaledWindow MapSurfaceToScaledWindow;
pcRdpgfxGetSurfaceIds GetSurfaceIds;
pcRdpgfxSetSurfaceData SetSurfaceData;

View File

@ -28,27 +28,48 @@ typedef struct _rdpgfx_server_private RdpgfxServerPrivate;
typedef BOOL (*psRdpgfxServerOpen)(RdpgfxServerContext* context);
typedef BOOL (*psRdpgfxServerClose)(RdpgfxServerContext* context);
typedef UINT(*psRdpgfxResetGraphics)(RdpgfxServerContext* context, RDPGFX_RESET_GRAPHICS_PDU* resetGraphics);
typedef UINT(*psRdpgfxResetGraphics)(RdpgfxServerContext* context,
RDPGFX_RESET_GRAPHICS_PDU* resetGraphics);
typedef UINT(*psRdpgfxStartFrame)(RdpgfxServerContext* context, RDPGFX_START_FRAME_PDU* startFrame);
typedef UINT(*psRdpgfxEndFrame)(RdpgfxServerContext* context, RDPGFX_END_FRAME_PDU* endFrame);
typedef UINT(*psRdpgfxSurfaceCommand)(RdpgfxServerContext* context, RDPGFX_SURFACE_COMMAND* cmd);
typedef UINT(*psRdpgfxSurfaceFrameCommand)(RdpgfxServerContext* context, RDPGFX_SURFACE_COMMAND* cmd, RDPGFX_START_FRAME_PDU* startFrame, RDPGFX_END_FRAME_PDU* endFrame);
typedef UINT(*psRdpgfxDeleteEncodingContext)(RdpgfxServerContext* context, RDPGFX_DELETE_ENCODING_CONTEXT_PDU* deleteEncodingContext);
typedef UINT(*psRdpgfxCreateSurface)(RdpgfxServerContext* context, RDPGFX_CREATE_SURFACE_PDU* createSurface);
typedef UINT(*psRdpgfxDeleteSurface)(RdpgfxServerContext* context, RDPGFX_DELETE_SURFACE_PDU* deleteSurface);
typedef UINT(*psRdpgfxSurfaceFrameCommand)(RdpgfxServerContext* context,
RDPGFX_SURFACE_COMMAND* cmd, RDPGFX_START_FRAME_PDU* startFrame, RDPGFX_END_FRAME_PDU* endFrame);
typedef UINT(*psRdpgfxDeleteEncodingContext)(RdpgfxServerContext* context,
RDPGFX_DELETE_ENCODING_CONTEXT_PDU* deleteEncodingContext);
typedef UINT(*psRdpgfxCreateSurface)(RdpgfxServerContext* context,
RDPGFX_CREATE_SURFACE_PDU* createSurface);
typedef UINT(*psRdpgfxDeleteSurface)(RdpgfxServerContext* context,
RDPGFX_DELETE_SURFACE_PDU* deleteSurface);
typedef UINT(*psRdpgfxSolidFill)(RdpgfxServerContext* context, RDPGFX_SOLID_FILL_PDU* solidFill);
typedef UINT(*psRdpgfxSurfaceToSurface)(RdpgfxServerContext* context, RDPGFX_SURFACE_TO_SURFACE_PDU* surfaceToSurface);
typedef UINT(*psRdpgfxSurfaceToCache)(RdpgfxServerContext* context, RDPGFX_SURFACE_TO_CACHE_PDU* surfaceToCache);
typedef UINT(*psRdpgfxCacheToSurface)(RdpgfxServerContext* context, RDPGFX_CACHE_TO_SURFACE_PDU* cacheToSurface);
typedef UINT(*psRdpgfxCacheImportOffer)(RdpgfxServerContext* context, RDPGFX_CACHE_IMPORT_OFFER_PDU* cacheImportOffer);
typedef UINT(*psRdpgfxCacheImportReply)(RdpgfxServerContext* context, RDPGFX_CACHE_IMPORT_REPLY_PDU* cacheImportReply);
typedef UINT(*psRdpgfxEvictCacheEntry)(RdpgfxServerContext* context, RDPGFX_EVICT_CACHE_ENTRY_PDU* evictCacheEntry);
typedef UINT(*psRdpgfxMapSurfaceToOutput)(RdpgfxServerContext* context, RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU* surfaceToOutput);
typedef UINT(*psRdpgfxMapSurfaceToWindow)(RdpgfxServerContext* context, RDPGFX_MAP_SURFACE_TO_WINDOW_PDU* surfaceToWindow);
typedef UINT(*psRdpgfxCapsAdvertise)(RdpgfxServerContext* context, RDPGFX_CAPS_ADVERTISE_PDU* capsAdvertise);
typedef UINT(*psRdpgfxCapsConfirm)(RdpgfxServerContext* context, RDPGFX_CAPS_CONFIRM_PDU* capsConfirm);
typedef UINT(*psRdpgfxFrameAcknowledge)(RdpgfxServerContext* context, RDPGFX_FRAME_ACKNOWLEDGE_PDU* frameAcknowledge);
typedef UINT(*psRdpgfxQoeFrameAcknowledge)(RdpgfxServerContext* context, RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU* qoeFrameAcknowledge);
typedef UINT(*psRdpgfxSurfaceToSurface)(RdpgfxServerContext* context,
RDPGFX_SURFACE_TO_SURFACE_PDU* surfaceToSurface);
typedef UINT(*psRdpgfxSurfaceToCache)(RdpgfxServerContext* context,
RDPGFX_SURFACE_TO_CACHE_PDU* surfaceToCache);
typedef UINT(*psRdpgfxCacheToSurface)(RdpgfxServerContext* context,
RDPGFX_CACHE_TO_SURFACE_PDU* cacheToSurface);
typedef UINT(*psRdpgfxCacheImportOffer)(RdpgfxServerContext* context,
RDPGFX_CACHE_IMPORT_OFFER_PDU* cacheImportOffer);
typedef UINT(*psRdpgfxCacheImportReply)(RdpgfxServerContext* context,
RDPGFX_CACHE_IMPORT_REPLY_PDU* cacheImportReply);
typedef UINT(*psRdpgfxEvictCacheEntry)(RdpgfxServerContext* context,
RDPGFX_EVICT_CACHE_ENTRY_PDU* evictCacheEntry);
typedef UINT(*psRdpgfxMapSurfaceToOutput)(RdpgfxServerContext* context,
RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU* surfaceToOutput);
typedef UINT(*psRdpgfxMapSurfaceToWindow)(RdpgfxServerContext* context,
RDPGFX_MAP_SURFACE_TO_WINDOW_PDU* surfaceToWindow);
typedef UINT(*psRdpgfxMapSurfaceToScaledOutput)(RdpgfxServerContext* context,
RDPGFX_MAP_SURFACE_TO_SCALED_OUTPUT_PDU* surfaceToOutput);
typedef UINT(*psRdpgfxMapSurfaceToScaledWindow)(RdpgfxServerContext* context,
RDPGFX_MAP_SURFACE_TO_SCALED_WINDOW_PDU* surfaceToWindow);
typedef UINT(*psRdpgfxCapsAdvertise)(RdpgfxServerContext* context,
RDPGFX_CAPS_ADVERTISE_PDU* capsAdvertise);
typedef UINT(*psRdpgfxCapsConfirm)(RdpgfxServerContext* context,
RDPGFX_CAPS_CONFIRM_PDU* capsConfirm);
typedef UINT(*psRdpgfxFrameAcknowledge)(RdpgfxServerContext* context,
RDPGFX_FRAME_ACKNOWLEDGE_PDU* frameAcknowledge);
typedef UINT(*psRdpgfxQoeFrameAcknowledge)(RdpgfxServerContext* context,
RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU* qoeFrameAcknowledge);
struct _rdpgfx_server_context
{
@ -75,6 +96,8 @@ struct _rdpgfx_server_context
psRdpgfxEvictCacheEntry EvictCacheEntry;
psRdpgfxMapSurfaceToOutput MapSurfaceToOutput;
psRdpgfxMapSurfaceToWindow MapSurfaceToWindow;
psRdpgfxMapSurfaceToScaledOutput MapSurfaceToScaledOutput;
psRdpgfxMapSurfaceToScaledWindow MapSurfaceToScaledWindow;
psRdpgfxCapsAdvertise CapsAdvertise;
psRdpgfxCapsConfirm CapsConfirm;
psRdpgfxFrameAcknowledge FrameAcknowledge;

View File

@ -1231,6 +1231,29 @@ fail:
return rc;
}
static UINT gdi_MapSurfaceToScaledOutput(RdpgfxClientContext* context,
const RDPGFX_MAP_SURFACE_TO_SCALED_OUTPUT_PDU* surfaceToOutput)
{
UINT rc = ERROR_INTERNAL_ERROR;
gdiGfxSurface* surface;
EnterCriticalSection(&context->mux);
surface = (gdiGfxSurface*) context->GetSurfaceData(context,
surfaceToOutput->surfaceId);
if (!surface)
goto fail;
surface->outputMapped = TRUE;
surface->outputOriginX = surfaceToOutput->outputOriginX;
surface->outputOriginY = surfaceToOutput->outputOriginY;
// TODO: Target x,y
region16_clear(&surface->invalidRegion);
rc = CHANNEL_RC_OK;
fail:
LeaveCriticalSection(&context->mux);
return rc;
}
/**
* Function description
*
@ -1242,6 +1265,12 @@ static UINT gdi_MapSurfaceToWindow(RdpgfxClientContext* context,
return CHANNEL_RC_OK;
}
static UINT gdi_MapSurfaceToScaledWindow(RdpgfxClientContext* context,
const RDPGFX_MAP_SURFACE_TO_SCALED_WINDOW_PDU* surfaceToWindow)
{
return CHANNEL_RC_OK;
}
BOOL gdi_graphics_pipeline_init(rdpGdi* gdi, RdpgfxClientContext* gfx)
{
if (!gdi || !gfx)
@ -1264,6 +1293,8 @@ BOOL gdi_graphics_pipeline_init(rdpGdi* gdi, RdpgfxClientContext* gfx)
gfx->EvictCacheEntry = gdi_EvictCacheEntry;
gfx->MapSurfaceToOutput = gdi_MapSurfaceToOutput;
gfx->MapSurfaceToWindow = gdi_MapSurfaceToWindow;
gfx->MapSurfaceToScaledOutput = gdi_MapSurfaceToScaledOutput;
gfx->MapSurfaceToScaledWindow = gdi_MapSurfaceToScaledWindow;
gfx->UpdateSurfaces = gdi_UpdateSurfaces;
InitializeCriticalSection(&gfx->mux);
PROFILER_CREATE(gfx->SurfaceProfiler, "GFX-PROFILER");

View File

@ -630,7 +630,7 @@ static UINT shadow_client_rdpgfx_caps_advertise(RdpgfxServerContext* context,
{
const RDPGFX_CAPSET* currentCaps = &capsAdvertise->capsSets[index];
if (currentCaps->version == RDPGFX_CAPVERSION_103)
if (currentCaps->version == RDPGFX_CAPVERSION_106)
{
RDPGFX_CAPSET caps = *currentCaps;
RDPGFX_CAPS_CONFIRM_PDU pdu;
@ -640,6 +640,75 @@ static UINT shadow_client_rdpgfx_caps_advertise(RdpgfxServerContext* context,
{
flags = pdu.capsSet->flags;
settings->GfxSmallCache = (flags & RDPGFX_CAPS_FLAG_SMALL_CACHE);
settings->GfxThinClient = (flags & RDPGFX_CAPS_FLAG_AVC_THINCLIENT);
#ifndef WITH_GFX_H264
settings->GfxAVC444v2 = settings->GfxAVC444 = settings->GfxH264 = FALSE;
pdu.capsSet->flags |= RDPGFX_CAPS_FLAG_AVC_DISABLED;
#else
settings->GfxAVC444v2 = settings->GfxAVC444 = settings->GfxH264 = !(flags &
RDPGFX_CAPS_FLAG_AVC_DISABLED);
#endif
}
return context->CapsConfirm(context, &pdu);
}
if (currentCaps->version == RDPGFX_CAPVERSION_105)
{
RDPGFX_CAPSET caps = *currentCaps;
RDPGFX_CAPS_CONFIRM_PDU pdu;
pdu.capsSet = &caps;
if (settings)
{
flags = pdu.capsSet->flags;
settings->GfxSmallCache = (flags & RDPGFX_CAPS_FLAG_SMALL_CACHE);
settings->GfxThinClient = (flags & RDPGFX_CAPS_FLAG_AVC_THINCLIENT);
#ifndef WITH_GFX_H264
settings->GfxAVC444v2 = settings->GfxAVC444 = settings->GfxH264 = FALSE;
pdu.capsSet->flags |= RDPGFX_CAPS_FLAG_AVC_DISABLED;
#else
settings->GfxAVC444v2 = settings->GfxAVC444 = settings->GfxH264 = !(flags &
RDPGFX_CAPS_FLAG_AVC_DISABLED);
#endif
}
return context->CapsConfirm(context, &pdu);
}
if (currentCaps->version == RDPGFX_CAPVERSION_104)
{
RDPGFX_CAPSET caps = *currentCaps;
RDPGFX_CAPS_CONFIRM_PDU pdu;
pdu.capsSet = &caps;
if (settings)
{
flags = pdu.capsSet->flags;
settings->GfxSmallCache = (flags & RDPGFX_CAPS_FLAG_SMALL_CACHE);
settings->GfxThinClient = (flags & RDPGFX_CAPS_FLAG_AVC_THINCLIENT);
#ifndef WITH_GFX_H264
settings->GfxAVC444v2 = settings->GfxAVC444 = settings->GfxH264 = FALSE;
pdu.capsSet->flags |= RDPGFX_CAPS_FLAG_AVC_DISABLED;
#else
settings->GfxAVC444v2 = settings->GfxAVC444 = settings->GfxH264 = !(flags &
RDPGFX_CAPS_FLAG_AVC_DISABLED);
#endif
}
return context->CapsConfirm(context, &pdu);
}
if (currentCaps->version == RDPGFX_CAPVERSION_103)
{
RDPGFX_CAPSET caps = *currentCaps;
RDPGFX_CAPS_CONFIRM_PDU pdu;
pdu.capsSet = &caps;
if (settings)
{
flags = pdu.capsSet->flags;
settings->GfxThinClient = (flags & RDPGFX_CAPS_FLAG_AVC_THINCLIENT);
#ifndef WITH_GFX_H264
settings->GfxAVC444v2 = settings->GfxAVC444 = settings->GfxH264 = FALSE;
pdu.capsSet->flags |= RDPGFX_CAPS_FLAG_AVC_DISABLED;