Updated GFX to 10.6 spec

This commit is contained in:
Armin Novak 2019-05-07 10:22:02 +02:00
parent 49805aae89
commit 3b7e46fb0e
7 changed files with 349 additions and 202 deletions

View File

@ -186,11 +186,6 @@ static UINT rdpgfx_send_supported_caps(RDPGFX_CHANNEL_CALLBACK* callback)
if (gfx->ThinClient)
caps10Flags |= RDPGFX_CAPS_FLAG_AVC_THINCLIENT;
/* Reports from Remmina suggest that current H264 decoder settings do
* not work with newer GFX protocol versions.
* Need to investigate this.
* Until resolved, disable the newer protocol versions. */
#if 0
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_103;
capsSet->length = 0x4;
@ -203,16 +198,10 @@ static UINT rdpgfx_send_supported_caps(RDPGFX_CHANNEL_CALLBACK* callback)
capsSet->version = RDPGFX_CAPVERSION_105;
capsSet->length = 0x4;
capsSet->flags = caps10Flags;
/* TODO: Until RDPGFX_MAP_SURFACE_TO_SCALED_OUTPUT_PDU and
* RDPGFX_MAP_SURFACE_TO_SCALED_WINDOW_PDU are not implemented do not
* announce the following version */
#if 0
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_106;
capsSet->length = 0x4;
capsSet->flags = caps10Flags;
#endif
#endif
}
if (context)
@ -684,6 +673,9 @@ static UINT rdpgfx_recv_end_frame_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
case RDPGFX_CAPVERSION_10:
case RDPGFX_CAPVERSION_102:
case RDPGFX_CAPVERSION_103:
case RDPGFX_CAPVERSION_104:
case RDPGFX_CAPVERSION_105:
case RDPGFX_CAPVERSION_106:
if (gfx->SendQoeAck)
{
RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU qoe;

View File

@ -38,6 +38,7 @@ static UINT xf_OutputUpdate(xfContext* xfc, xfGfxSurface* surface)
RECTANGLE_16 surfaceRect;
rdpGdi* gdi;
UINT32 nbRects, x;
double sx, sy;
const RECTANGLE_16* rects;
gdi = xfc->context.gdi;
surfaceX = surface->gdi.outputOriginX;
@ -51,6 +52,8 @@ static UINT xf_OutputUpdate(xfContext* xfc, xfGfxSurface* surface)
XSetFillStyle(xfc->display, xfc->gc, FillSolid);
region16_intersect_rect(&(surface->gdi.invalidRegion),
&(surface->gdi.invalidRegion), &surfaceRect);
sx = surface->gdi.outputTargetWidth / (double)surface->gdi.width;
sy = surface->gdi.outputTargetHeight / (double)surface->gdi.height;
if (!(rects = region16_rects(&surface->gdi.invalidRegion, &nbRects)))
return CHANNEL_RC_OK;
@ -59,19 +62,21 @@ static UINT xf_OutputUpdate(xfContext* xfc, xfGfxSurface* surface)
{
const UINT32 nXSrc = rects[x].left;
const UINT32 nYSrc = rects[x].top;
const UINT32 width = rects[x].right - nXSrc;
const UINT32 height = rects[x].bottom - nYSrc;
const UINT32 nXDst = surfaceX + nXSrc;
const UINT32 nYDst = surfaceY + nYSrc;
const UINT32 swidth = rects[x].right - nXSrc;
const UINT32 sheight = rects[x].bottom - nYSrc;
const UINT32 nXDst = surfaceX + nXSrc * sx;
const UINT32 nYDst = surfaceY + nYSrc * sy;
const UINT32 dwidth = swidth * sx;;
const UINT32 dheight = sheight * sy;
if (surface->stage)
{
if (!freerdp_image_copy(surface->stage, gdi->dstFormat,
surface->stageScanline, nXSrc, nYSrc,
width, height,
surface->gdi.data, surface->gdi.format,
surface->gdi.scanline, nXSrc, nYSrc,
NULL, FREERDP_FLIP_NONE))
if (!freerdp_image_scale(surface->stage, gdi->dstFormat,
surface->stageScanline, nXSrc, nYSrc,
dwidth, dheight,
surface->gdi.data, surface->gdi.format,
surface->gdi.scanline, nXSrc, nYSrc,
swidth, sheight))
goto fail;
}
@ -79,9 +84,9 @@ static UINT xf_OutputUpdate(xfContext* xfc, xfGfxSurface* surface)
{
XPutImage(xfc->display, xfc->primary, xfc->gc,
surface->image, nXSrc, nYSrc,
nXDst, nYDst, width, height);
nXDst, nYDst, dwidth, dheight);
xf_lock_x11(xfc, FALSE);
xf_rail_paint(xfc, nXDst, nYDst, nXDst + width, nYDst + height);
xf_rail_paint(xfc, nXDst, nYDst, nXDst + dwidth, nYDst + dheight);
xf_unlock_x11(xfc, FALSE);
}
else
@ -90,15 +95,15 @@ static UINT xf_OutputUpdate(xfContext* xfc, xfGfxSurface* surface)
|| xfc->context.settings->MultiTouchGestures)
{
XPutImage(xfc->display, xfc->primary, xfc->gc, surface->image,
nXSrc, nYSrc, nXDst, nYDst, width, height);
xf_draw_screen(xfc, nXDst, nYDst, width, height);
nXSrc, nYSrc, nXDst, nYDst, dwidth, dheight);
xf_draw_screen(xfc, nXDst, nYDst, dwidth, dheight);
}
else
#endif
{
XPutImage(xfc->display, xfc->drawable, xfc->gc,
surface->image, nXSrc, nYSrc,
nXDst, nYDst, width, height);
nXDst, nYDst, dwidth, dheight);
}
}
@ -115,7 +120,6 @@ static UINT xf_UpdateSurfaces(RdpgfxClientContext* context)
UINT16 count;
UINT32 index;
UINT status = CHANNEL_RC_OK;
xfGfxSurface* surface;
UINT16* pSurfaceIds = NULL;
rdpGdi* gdi = (rdpGdi*)context->custom;
xfContext* xfc = (xfContext*) gdi->context;
@ -134,12 +138,19 @@ static UINT xf_UpdateSurfaces(RdpgfxClientContext* context)
for (index = 0; index < count; index++)
{
surface = (xfGfxSurface*) context->GetSurfaceData(context, pSurfaceIds[index]);
xfGfxSurface* surface = (xfGfxSurface*) context->GetSurfaceData(context, pSurfaceIds[index]);
if (!surface || !surface->gdi.outputMapped)
if (!surface)
continue;
status = xf_OutputUpdate(xfc, surface);
/* Already handled in UpdateSurfaceArea callbacks */
if (surface->gdi.windowId != 0)
continue;
status = ERROR_INTERNAL_ERROR;
if (surface->gdi.outputMapped)
status = xf_OutputUpdate(xfc, surface);
if (status != 0)
break;
@ -182,8 +193,8 @@ UINT xf_OutputExpose(xfContext* xfc, UINT32 x, UINT32 y,
surfaceRect.left = surface->gdi.outputOriginX;
surfaceRect.top = surface->gdi.outputOriginY;
surfaceRect.right = surface->gdi.outputOriginX + surface->gdi.width;
surfaceRect.bottom = surface->gdi.outputOriginY + surface->gdi.height;
surfaceRect.right = surface->gdi.outputOriginX + surface->gdi.outputTargetWidth;
surfaceRect.bottom = surface->gdi.outputOriginY + surface->gdi.outputTargetHeight;
if (rectangles_intersection(&invalidRect, &surfaceRect, &intersection))
{
@ -363,6 +374,9 @@ static UINT xf_DeleteSurface(RdpgfxClientContext* context,
if (surface)
{
if (surface->gdi.windowId > 0)
IFCALL(context->UnmapWindowForSurface, context, surface->gdi.windowId);
#ifdef WITH_GFX_H264
h264_context_free(surface->gdi.h264);
#endif
@ -386,9 +400,16 @@ static UINT xf_DeleteSurface(RdpgfxClientContext* context,
}
void xf_graphics_pipeline_init(xfContext* xfc, RdpgfxClientContext* gfx)
{
xf_graphics_pipeline_init_ex(xfc, gfx, NULL, NULL, NULL);
}
void xf_graphics_pipeline_init_ex(xfContext* xfc, RdpgfxClientContext* gfx,
pcRdpgfxMapWindowForSurface map, pcRdpgfxUnmapWindowForSurface unmap,
pcRdpgfxUpdateSurfaceArea update)
{
rdpGdi* gdi = xfc->context.gdi;
gdi_graphics_pipeline_init(gdi, gfx);
gdi_graphics_pipeline_init_ex(gdi, gfx, map, unmap, update);
gfx->UpdateSurfaces = xf_UpdateSurfaces;
gfx->CreateSurface = xf_CreateSurface;
gfx->DeleteSurface = xf_DeleteSurface;

View File

@ -51,6 +51,10 @@ UINT xf_OutputExpose(xfContext* xfc, UINT32 x, UINT32 y,
UINT32 width, UINT32 height);
void xf_graphics_pipeline_init(xfContext* xfc, RdpgfxClientContext* gfx);
void xf_graphics_pipeline_init_ex(xfContext* xfc, RdpgfxClientContext* gfx,
pcRdpgfxMapWindowForSurface map,
pcRdpgfxUnmapWindowForSurface unmap,
pcRdpgfxUpdateSurfaceArea update);
void xf_graphics_pipeline_uninit(xfContext* xfc, RdpgfxClientContext* gfx);
#endif /* FREERDP_CLIENT_X11_GFX_H */

View File

@ -93,6 +93,10 @@ typedef UINT(*pcRdpgfxCapsConfirm)(RdpgfxClientContext* context,
typedef UINT(*pcRdpgfxFrameAcknowledge)(RdpgfxClientContext* context,
const RDPGFX_FRAME_ACKNOWLEDGE_PDU* frameAcknowledge);
typedef UINT(*pcRdpgfxMapWindowForSurface)(RdpgfxClientContext* context, UINT16 surfaceID,
UINT64 windowID);
typedef UINT(*pcRdpgfxUnmapWindowForSurface)(RdpgfxClientContext* context, UINT64 windowID);
struct _rdpgfx_client_context
{
void* handle;
@ -135,6 +139,13 @@ struct _rdpgfx_client_context
pcRdpgfxUpdateSurfaces UpdateSurfaces;
pcRdpgfxUpdateSurfaceArea UpdateSurfaceArea;
/* These callbacks allow crating/destroying a window directly
* mapped to a surface.
* NOTE: The surface is already locked.
*/
pcRdpgfxMapWindowForSurface MapWindowForSurface;
pcRdpgfxUnmapWindowForSurface UnmapWindowForSurface;
CRITICAL_SECTION mux;
PROFILER_DEFINE(SurfaceProfiler)
};

View File

@ -37,6 +37,9 @@ struct gdi_gfx_surface
UINT32 outputOriginX;
UINT32 outputOriginY;
REGION16 invalidRegion;
UINT64 windowId;
UINT32 outputTargetWidth;
UINT32 outputTargetHeight;
};
typedef struct gdi_gfx_surface gdiGfxSurface;
@ -56,6 +59,10 @@ extern "C" {
#endif
FREERDP_API BOOL gdi_graphics_pipeline_init(rdpGdi* gdi, RdpgfxClientContext* gfx);
FREERDP_API BOOL gdi_graphics_pipeline_init_ex(rdpGdi* gdi, RdpgfxClientContext* gfx,
pcRdpgfxMapWindowForSurface map,
pcRdpgfxUnmapWindowForSurface unmap,
pcRdpgfxUpdateSurfaceArea update);
FREERDP_API void gdi_graphics_pipeline_uninit(rdpGdi* gdi, RdpgfxClientContext* gfx);
#ifdef __cplusplus

View File

@ -100,13 +100,11 @@ fail:
static UINT gdi_OutputUpdate(rdpGdi* gdi, gdiGfxSurface* surface)
{
UINT rc = ERROR_INTERNAL_ERROR;
UINT32 nXDst, nYDst;
UINT32 nXSrc, nYSrc;
UINT16 width, height;
UINT32 surfaceX, surfaceY;
RECTANGLE_16 surfaceRect;
const RECTANGLE_16* rects;
UINT32 i, nbRects;
double sx, sy;
rdpUpdate* update = gdi->context->update;
if (gdi->suppressOutput)
@ -120,6 +118,8 @@ static UINT gdi_OutputUpdate(rdpGdi* gdi, gdiGfxSurface* surface)
surfaceRect.bottom = surface->height;
region16_intersect_rect(&(surface->invalidRegion),
&(surface->invalidRegion), &surfaceRect);
sx = surface->outputTargetWidth / (double)surface->width;
sy = surface->outputTargetHeight / (double)surface->height;
if (!(rects = region16_rects(&surface->invalidRegion, &nbRects)) || !nbRects)
return CHANNEL_RC_OK;
@ -129,21 +129,22 @@ static UINT gdi_OutputUpdate(rdpGdi* gdi, gdiGfxSurface* surface)
for (i = 0; i < nbRects; i++)
{
nXSrc = rects[i].left;
nYSrc = rects[i].top;
nXDst = surfaceX + nXSrc;
nYDst = surfaceY + nYSrc;
width = rects[i].right - rects[i].left;
height = rects[i].bottom - rects[i].top;
const UINT32 nXSrc = rects[i].left;
const UINT32 nYSrc = rects[i].top;
const UINT32 nXDst = surfaceX + nXSrc * sx;
const UINT32 nYDst = surfaceY + nYSrc * sy;
const UINT32 swidth = rects[i].right - rects[i].left;
const UINT32 sheight = rects[i].bottom - rects[i].top;
const UINT32 dwidth = swidth * sx;
const UINT32 dheight = sheight * sy;
if (!freerdp_image_copy(gdi->primary_buffer, gdi->primary->hdc->format,
gdi->stride,
nXDst, nYDst, width, height,
surface->data, surface->format,
surface->scanline, nXSrc, nYSrc, NULL, FREERDP_FLIP_NONE))
if (!freerdp_image_scale(gdi->primary_buffer, gdi->dstFormat,
gdi->stride, nXDst, nYDst, dwidth, dheight,
surface->data, surface->format,
surface->scanline, nXSrc, nYSrc, swidth, sheight))
return CHANNEL_RC_NULL_DATA;
gdi_InvalidateRegion(gdi->primary->hdc, nXDst, nYDst, width, height);
gdi_InvalidateRegion(gdi->primary->hdc, nXDst, nYDst, dwidth, dheight);
}
if (!IFCALLRESULT(FALSE, update->EndPaint, gdi->context))
@ -175,10 +176,20 @@ static UINT gdi_UpdateSurfaces(RdpgfxClientContext* context)
{
surface = (gdiGfxSurface*) context->GetSurfaceData(context, pSurfaceIds[index]);
if (!surface || !surface->outputMapped)
if (!surface)
continue;
status = gdi_OutputUpdate(gdi, surface);
/* Already handled in UpdateSurfaceArea callbacks */
if (context->UpdateSurfaceArea)
{
if (surface->windowId != 0)
continue;
}
status = ERROR_INTERNAL_ERROR;
if (surface->outputMapped)
status = gdi_OutputUpdate(gdi, surface);
if (status != CHANNEL_RC_OK)
break;
@ -612,6 +623,41 @@ fail:
#endif
}
static BOOL gdi_apply_alpha(BYTE* data, UINT32 format, UINT32 stride,
RECTANGLE_16* rect, UINT32 startOffsetX, UINT32 count, BYTE a)
{
UINT32 y;
UINT32 written = 0;
BOOL first = TRUE;
const UINT32 bpp = GetBytesPerPixel(format);
for (y = rect->top; y < rect->bottom; y++)
{
UINT32 x;
BYTE* line = &data[stride * y];
for (x = first ? rect->left + startOffsetX : rect->left; x < rect->right; x++)
{
UINT32 color;
BYTE r, g, b;
BYTE* src;
if (written == count)
return TRUE;
src = &line[x * bpp];
color = ReadColor(src, format);
SplitColor(color, format, &r, &g, &b, NULL, NULL);
color = FreeRDPGetColor(format, r, g, b, a);
WriteColor(src, format, color);
written ++;
}
first = FALSE;
}
return TRUE;
}
/**
* Function description
*
@ -621,9 +667,15 @@ static UINT gdi_SurfaceCommand_Alpha(rdpGdi* gdi, RdpgfxClientContext* context,
const RDPGFX_SURFACE_COMMAND* cmd)
{
UINT status = CHANNEL_RC_OK;
UINT32 color;
UINT16 alphaSig, compressed;
gdiGfxSurface* surface;
RECTANGLE_16 invalidRect;
wStream s;
Stream_StaticInit(&s, cmd->data, cmd->length);
if (Stream_GetRemainingLength(&s) < 4)
return ERROR_INVALID_DATA;
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
if (!surface)
@ -633,13 +685,85 @@ static UINT gdi_SurfaceCommand_Alpha(rdpGdi* gdi, RdpgfxClientContext* context,
return ERROR_NOT_FOUND;
}
WLog_WARN(TAG, "TODO gdi_SurfaceCommand_Alpha: status: %"PRIu32"", status);
/* fill with green for now to distinguish from the rest */
color = FreeRDPGetColor(surface->format, 0x00, 0xFF, 0x00, 0xFF);
Stream_Read_UINT16(&s, alphaSig);
Stream_Read_UINT16(&s, compressed);
if (!freerdp_image_fill(surface->data, surface->format, surface->scanline,
cmd->left, cmd->top, cmd->width, cmd->height, color))
return ERROR_INTERNAL_ERROR;
if (alphaSig != 0x414C)
return ERROR_INVALID_DATA;
if (compressed == 0)
{
UINT32 x, y;
if (Stream_GetRemainingLength(&s) < cmd->height * cmd->width)
return ERROR_INVALID_DATA;
for (y = cmd->top; y < cmd->top + cmd->height; y++)
{
BYTE* line = &surface->data[surface->scanline * y];
for (x = cmd->left; x < cmd->left + cmd->width; x++)
{
UINT32 color;
BYTE r, g, b, a;
BYTE* src = &line[x * GetBytesPerPixel(surface->format)];
Stream_Read_UINT8(&s, a);
color = ReadColor(src, surface->format);
SplitColor(color, surface->format, &r, &g, &b, NULL, NULL);
color = FreeRDPGetColor(surface->format, r, g, b, a);
WriteColor(src, surface->format, color);
}
}
}
else
{
UINT32 startOffsetX = 0;
RECTANGLE_16 rect;
rect.left = cmd->left;
rect.top = cmd->top;
rect.right = cmd->left + cmd->width;
rect.bottom = cmd->top + cmd->height;
while (rect.top < rect.bottom)
{
UINT32 count;
BYTE a;
if (Stream_GetRemainingLength(&s) < 2)
return ERROR_INVALID_DATA;
Stream_Read_UINT8(&s, a);
Stream_Read_UINT8(&s, count);
if (count >= 0xFF)
{
if (Stream_GetRemainingLength(&s) < 2)
return ERROR_INVALID_DATA;
Stream_Read_UINT16(&s, count);
if (count >= 0xFFFF)
{
if (Stream_GetRemainingLength(&s) < 4)
return ERROR_INVALID_DATA;
Stream_Read_UINT32(&s, count);
}
}
if (!gdi_apply_alpha(surface->data, surface->format, surface->scanline, &rect, startOffsetX, count,
a))
return ERROR_INTERNAL_ERROR;
startOffsetX += count;
while (startOffsetX >= cmd->width)
{
startOffsetX -= cmd->width;
rect.top++;
}
}
}
invalidRect.left = cmd->left;
invalidRect.top = cmd->top;
@ -896,6 +1020,9 @@ static UINT gdi_DeleteSurface(RdpgfxClientContext* context,
if (surface)
{
if (surface->windowId != 0)
rc = IFCALLRESULT(CHANNEL_RC_OK, context->UnmapWindowForSurface, context, surface->windowId);
#ifdef WITH_GFX_H264
h264_context_free(surface->h264);
#endif
@ -1227,6 +1354,8 @@ static UINT gdi_MapSurfaceToOutput(RdpgfxClientContext* context,
surface->outputMapped = TRUE;
surface->outputOriginX = surfaceToOutput->outputOriginX;
surface->outputOriginY = surfaceToOutput->outputOriginY;
surface->outputTargetWidth = surface->width;
surface->outputTargetHeight = surface->height;
region16_clear(&surface->invalidRegion);
rc = CHANNEL_RC_OK;
fail:
@ -1249,7 +1378,8 @@ static UINT gdi_MapSurfaceToScaledOutput(RdpgfxClientContext* context,
surface->outputMapped = TRUE;
surface->outputOriginX = surfaceToOutput->outputOriginX;
surface->outputOriginY = surfaceToOutput->outputOriginY;
// TODO: Target x,y
surface->outputTargetWidth = surfaceToOutput->targetWidth;
surface->outputTargetHeight = surfaceToOutput->targetHeight;
region16_clear(&surface->invalidRegion);
rc = CHANNEL_RC_OK;
fail:
@ -1265,16 +1395,74 @@ fail:
static UINT gdi_MapSurfaceToWindow(RdpgfxClientContext* context,
const RDPGFX_MAP_SURFACE_TO_WINDOW_PDU* surfaceToWindow)
{
return CHANNEL_RC_OK;
UINT rc = ERROR_INTERNAL_ERROR;
gdiGfxSurface* surface;
EnterCriticalSection(&context->mux);
surface = (gdiGfxSurface*) context->GetSurfaceData(context,
surfaceToWindow->surfaceId);
if (!surface)
goto fail;
if (surface->windowId != 0)
{
if (surface->windowId != surfaceToWindow->windowId)
goto fail;
}
surface->windowId = surfaceToWindow->windowId;
surface->width = surfaceToWindow->mappedWidth;
surface->height = surfaceToWindow->mappedHeight;
surface->outputTargetWidth = surfaceToWindow->mappedWidth;
surface->outputTargetHeight = surfaceToWindow->mappedHeight;
rc = IFCALLRESULT(CHANNEL_RC_OK, context->MapWindowForSurface, context,
surfaceToWindow->surfaceId,
surfaceToWindow->windowId);
fail:
LeaveCriticalSection(&context->mux);
return rc;
}
static UINT gdi_MapSurfaceToScaledWindow(RdpgfxClientContext* context,
const RDPGFX_MAP_SURFACE_TO_SCALED_WINDOW_PDU* surfaceToWindow)
{
return CHANNEL_RC_OK;
UINT rc = ERROR_INTERNAL_ERROR;
gdiGfxSurface* surface;
EnterCriticalSection(&context->mux);
surface = (gdiGfxSurface*) context->GetSurfaceData(context,
surfaceToWindow->surfaceId);
if (!surface)
goto fail;
if (surface->windowId != 0)
{
if (surface->windowId != surfaceToWindow->windowId)
goto fail;
}
surface->windowId = surfaceToWindow->windowId;
surface->width = surfaceToWindow->mappedWidth;
surface->height = surfaceToWindow->mappedHeight;
surface->outputTargetWidth = surfaceToWindow->targetWidth;
surface->outputTargetHeight = surfaceToWindow->targetHeight;
rc = IFCALLRESULT(CHANNEL_RC_OK, context->MapWindowForSurface, context,
surfaceToWindow->surfaceId,
surfaceToWindow->windowId);
fail:
LeaveCriticalSection(&context->mux);
return rc;
}
BOOL gdi_graphics_pipeline_init(rdpGdi* gdi, RdpgfxClientContext* gfx)
{
return gdi_graphics_pipeline_init_ex(gdi, gfx, NULL, NULL, NULL);
}
BOOL gdi_graphics_pipeline_init_ex(rdpGdi* gdi, RdpgfxClientContext* gfx,
pcRdpgfxMapWindowForSurface map,
pcRdpgfxUnmapWindowForSurface unmap,
pcRdpgfxUpdateSurfaceArea update)
{
if (!gdi || !gfx)
return FALSE;
@ -1299,6 +1487,9 @@ BOOL gdi_graphics_pipeline_init(rdpGdi* gdi, RdpgfxClientContext* gfx)
gfx->MapSurfaceToScaledOutput = gdi_MapSurfaceToScaledOutput;
gfx->MapSurfaceToScaledWindow = gdi_MapSurfaceToScaledWindow;
gfx->UpdateSurfaces = gdi_UpdateSurfaces;
gfx->MapWindowForSurface = map;
gfx->UnmapWindowForSurface = unmap;
gfx->UpdateSurfaceArea = update;
InitializeCriticalSection(&gfx->mux);
PROFILER_CREATE(gfx->SurfaceProfiler, "GFX-PROFILER");
return TRUE;

View File

@ -613,6 +613,47 @@ static UINT shadow_client_rdpgfx_frame_acknowledge(RdpgfxServerContext* context,
return CHANNEL_RC_OK;
}
static BOOL shadow_client_caps_test_version(RdpgfxServerContext* context,
const RDPGFX_CAPSET* capsSets,
UINT32 capsSetCount,
UINT32 capsVersion, UINT* rc)
{
UINT32 flags = 0;
UINT32 index;
rdpSettings* settings;
settings = context->rdpcontext->settings;
for (index = 0; index < capsSetCount; index++)
{
const RDPGFX_CAPSET* currentCaps = &capsSets[index];
if (currentCaps->version == capsVersion)
{
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);
#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
}
*rc = context->CapsConfirm(context, &pdu);
return TRUE;
}
}
return FALSE;
}
/**
* Function description
*
@ -622,159 +663,39 @@ static UINT shadow_client_rdpgfx_caps_advertise(RdpgfxServerContext* context,
const RDPGFX_CAPS_ADVERTISE_PDU* capsAdvertise)
{
UINT16 index;
UINT rc;
rdpSettings* settings = context->rdpcontext->settings;
UINT32 flags = 0;
/* Request full screen update for new gfx channel */
shadow_client_refresh_rect((rdpShadowClient*)context->custom, 0, NULL);
for (index = 0; index < capsAdvertise->capsSetCount; index++)
{
const RDPGFX_CAPSET* currentCaps = &capsAdvertise->capsSets[index];
if (shadow_client_caps_test_version(context, capsAdvertise->capsSets, capsAdvertise->capsSetCount,
RDPGFX_CAPVERSION_106, &rc))
return rc;
if (currentCaps->version == RDPGFX_CAPVERSION_106)
{
RDPGFX_CAPSET caps = *currentCaps;
RDPGFX_CAPS_CONFIRM_PDU pdu;
pdu.capsSet = &caps;
if (shadow_client_caps_test_version(context, capsAdvertise->capsSets, capsAdvertise->capsSetCount,
RDPGFX_CAPVERSION_105, &rc))
return rc;
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
}
if (shadow_client_caps_test_version(context, capsAdvertise->capsSets, capsAdvertise->capsSetCount,
RDPGFX_CAPVERSION_104, &rc))
return rc;
return context->CapsConfirm(context, &pdu);
}
if (shadow_client_caps_test_version(context, capsAdvertise->capsSets, capsAdvertise->capsSetCount,
RDPGFX_CAPVERSION_103, &rc))
return rc;
if (currentCaps->version == RDPGFX_CAPVERSION_105)
{
RDPGFX_CAPSET caps = *currentCaps;
RDPGFX_CAPS_CONFIRM_PDU pdu;
pdu.capsSet = &caps;
if (shadow_client_caps_test_version(context, capsAdvertise->capsSets, capsAdvertise->capsSetCount,
RDPGFX_CAPVERSION_102, &rc))
return rc;
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
}
if (shadow_client_caps_test_version(context, capsAdvertise->capsSets, capsAdvertise->capsSetCount,
RDPGFX_CAPVERSION_101, &rc))
return rc;
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;
#else
settings->GfxAVC444v2 = settings->GfxAVC444 = settings->GfxH264 = !(flags &
RDPGFX_CAPS_FLAG_AVC_DISABLED);
#endif
}
return context->CapsConfirm(context, &pdu);
}
}
for (index = 0; index < capsAdvertise->capsSetCount; index++)
{
const RDPGFX_CAPSET* currentCaps = &capsAdvertise->capsSets[index];
if (currentCaps->version == RDPGFX_CAPVERSION_102)
{
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);
#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);
}
}
for (index = 0; index < capsAdvertise->capsSetCount; index++)
{
const RDPGFX_CAPSET* currentCaps = &capsAdvertise->capsSets[index];
if (currentCaps->version == RDPGFX_CAPVERSION_10)
{
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);
#ifndef WITH_GFX_H264
settings->GfxAVC444v2 = settings->GfxAVC444 = settings->GfxH264 = FALSE;
pdu.capsSet->flags |= RDPGFX_CAPS_FLAG_AVC_DISABLED;
#else
settings->GfxAVC444 = settings->GfxH264 = !(flags & RDPGFX_CAPS_FLAG_AVC_DISABLED);
#endif
}
return context->CapsConfirm(context, &pdu);
}
}
if (shadow_client_caps_test_version(context, capsAdvertise->capsSets, capsAdvertise->capsSetCount,
RDPGFX_CAPVERSION_10, &rc))
return rc;
for (index = 0; index < capsAdvertise->capsSetCount; index++)
{