From 4ab373aced982aac30346562944090940b3138a6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 13 Oct 2015 14:49:30 -0400 Subject: [PATCH] xfreerdp: fix multiple egfx context support in X11 GFX --- client/X11/xf_gfx.c | 93 ++++++++++++++++++++++++++---------------------- client/X11/xf_gfx.h | 1 + libfreerdp/core/codecs.c | 14 ++++---- 3 files changed, 58 insertions(+), 50 deletions(-) diff --git a/client/X11/xf_gfx.c b/client/X11/xf_gfx.c index 4e1c037..8a53ede 100644 --- a/client/X11/xf_gfx.c +++ b/client/X11/xf_gfx.c @@ -33,14 +33,12 @@ */ UINT xf_ResetGraphics(RdpgfxClientContext* context, RDPGFX_RESET_GRAPHICS_PDU* resetGraphics) { - UINT16 count; int index; + UINT16 count; xfGfxSurface* surface; UINT16* pSurfaceIds = NULL; xfContext* xfc = (xfContext*) context->custom; - freerdp_client_codecs_reset(xfc->codecs, FREERDP_CODEC_ALL); - context->GetSurfaceIds(context, &pSurfaceIds, &count); for (index = 0; index < count; index++) @@ -50,11 +48,15 @@ UINT xf_ResetGraphics(RdpgfxClientContext* context, RDPGFX_RESET_GRAPHICS_PDU* r if (!surface || !surface->outputMapped) continue; + freerdp_client_codecs_reset(surface->codecs, FREERDP_CODEC_ALL); + region16_clear(&surface->invalidRegion); } free(pSurfaceIds); + freerdp_client_codecs_reset(xfc->codecs, FREERDP_CODEC_ALL); + xfc->graphicsReset = TRUE; return CHANNEL_RC_OK; @@ -288,15 +290,15 @@ UINT xf_SurfaceCommand_RemoteFX(xfContext* xfc, RdpgfxClientContext* context, RD REGION16 clippingRects; RECTANGLE_16 clippingRect; - if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_REMOTEFX)) - return ERROR_INTERNAL_ERROR; - surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return ERROR_INTERNAL_ERROR; - if (!(message = rfx_process_message(xfc->codecs->rfx, cmd->data, cmd->length))) + if (!freerdp_client_codecs_prepare(surface->codecs, FREERDP_CODEC_REMOTEFX)) + return ERROR_INTERNAL_ERROR; + + if (!(message = rfx_process_message(surface->codecs->rfx, cmd->data, cmd->length))) { WLog_ERR(TAG, "Failed to process RemoteFX message"); return ERROR_INTERNAL_ERROR; @@ -346,7 +348,7 @@ UINT xf_SurfaceCommand_RemoteFX(xfContext* xfc, RdpgfxClientContext* context, RD region16_uninit(&updateRegion); } - rfx_message_free(xfc->codecs->rfx, message); + rfx_message_free(surface->codecs->rfx, message); region16_uninit(&clippingRects); @@ -368,14 +370,14 @@ UINT xf_SurfaceCommand_ClearCodec(xfContext* xfc, RdpgfxClientContext* context, xfGfxSurface* surface; RECTANGLE_16 invalidRect; - if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_CLEARCODEC)) - return ERROR_INTERNAL_ERROR; - surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return ERROR_INTERNAL_ERROR; + if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_CLEARCODEC)) + return ERROR_INTERNAL_ERROR; + DstData = surface->data; status = clear_decompress(xfc->codecs->clear, cmd->data, cmd->length, &DstData, @@ -383,7 +385,7 @@ UINT xf_SurfaceCommand_ClearCodec(xfContext* xfc, RdpgfxClientContext* context, if (status < 0) { - WLog_ERR(TAG, "clear_decompress failure: %d\n", status); + WLog_ERR(TAG, "clear_decompress failure: %d", status); return ERROR_INTERNAL_ERROR; } @@ -412,17 +414,17 @@ UINT xf_SurfaceCommand_Planar(xfContext* xfc, RdpgfxClientContext* context, RDPG xfGfxSurface* surface; RECTANGLE_16 invalidRect; - if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_PLANAR)) - return ERROR_INTERNAL_ERROR; - surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return ERROR_INTERNAL_ERROR; + if (!freerdp_client_codecs_prepare(surface->codecs, FREERDP_CODEC_PLANAR)) + return ERROR_INTERNAL_ERROR; + DstData = surface->data; - status = planar_decompress(xfc->codecs->planar, cmd->data, cmd->length, &DstData, + status = planar_decompress(surface->codecs->planar, cmd->data, cmd->length, &DstData, surface->format, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height, FALSE); invalidRect.left = cmd->left; @@ -448,15 +450,17 @@ UINT xf_SurfaceCommand_H264(xfContext* xfc, RdpgfxClientContext* context, RDPGFX int status; UINT32 i; BYTE* DstData = NULL; - H264_CONTEXT* h264; xfGfxSurface* surface; RDPGFX_H264_METABLOCK* meta; RDPGFX_H264_BITMAP_STREAM* bs; - if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_H264)) + surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); + + if (!surface) return ERROR_INTERNAL_ERROR; - h264 = xfc->codecs->h264; + if (!freerdp_client_codecs_prepare(surface->codecs, FREERDP_CODEC_H264)) + return ERROR_INTERNAL_ERROR; bs = (RDPGFX_H264_BITMAP_STREAM*) cmd->extra; @@ -465,16 +469,11 @@ UINT xf_SurfaceCommand_H264(xfContext* xfc, RdpgfxClientContext* context, RDPGFX meta = &(bs->meta); - surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); - - if (!surface) - return ERROR_INTERNAL_ERROR; - DstData = surface->data; - status = h264_decompress(xfc->codecs->h264, bs->data, bs->length, &DstData, - surface->format, surface->scanline , surface->width, - surface->height, meta->regionRects, meta->numRegionRects); + status = h264_decompress(surface->codecs->h264, bs->data, bs->length, &DstData, + surface->format, surface->scanline , surface->width, + surface->height, meta->regionRects, meta->numRegionRects); if (status < 0) { @@ -504,14 +503,14 @@ UINT xf_SurfaceCommand_Alpha(xfContext* xfc, RdpgfxClientContext* context, RDPGF xfGfxSurface* surface; RECTANGLE_16 invalidRect; - if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_ALPHACODEC)) - return ERROR_INTERNAL_ERROR; - surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return ERROR_INTERNAL_ERROR; + if (!freerdp_client_codecs_prepare(surface->codecs, FREERDP_CODEC_ALPHACODEC)) + return ERROR_INTERNAL_ERROR; + WLog_DBG(TAG, "xf_SurfaceCommand_Alpha: status: %d", status); /* fill with green for now to distinguish from the rest */ @@ -555,19 +554,19 @@ UINT xf_SurfaceCommand_Progressive(xfContext* xfc, RdpgfxClientContext* context, RFX_PROGRESSIVE_TILE* tile; PROGRESSIVE_BLOCK_REGION* region; - if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_PROGRESSIVE)) - return ERROR_INTERNAL_ERROR; - surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return ERROR_INTERNAL_ERROR; - progressive_create_surface_context(xfc->codecs->progressive, cmd->surfaceId, surface->width, surface->height); + if (!freerdp_client_codecs_prepare(surface->codecs, FREERDP_CODEC_PROGRESSIVE)) + return ERROR_INTERNAL_ERROR; + + progressive_create_surface_context(surface->codecs->progressive, cmd->surfaceId, surface->width, surface->height); DstData = surface->data; - status = progressive_decompress(xfc->codecs->progressive, cmd->data, cmd->length, &DstData, + status = progressive_decompress(surface->codecs->progressive, cmd->data, cmd->length, &DstData, surface->format, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height, cmd->surfaceId); if (status < 0) @@ -576,7 +575,7 @@ UINT xf_SurfaceCommand_Progressive(xfContext* xfc, RdpgfxClientContext* context, return ERROR_INTERNAL_ERROR; } - region = &(xfc->codecs->progressive->region); + region = &(surface->codecs->progressive->region); region16_init(&clippingRects); @@ -707,6 +706,11 @@ UINT xf_CreateSurface(RdpgfxClientContext* context, RDPGFX_CREATE_SURFACE_PDU* c if (!surface) return CHANNEL_RC_NO_MEMORY; + surface->codecs = codecs_new((rdpContext*) xfc); + + if (!surface->codecs) + return CHANNEL_RC_NO_MEMORY; + surface->surfaceId = createSurface->surfaceId; surface->width = (UINT32) createSurface->width; surface->height = (UINT32) createSurface->height; @@ -721,7 +725,7 @@ UINT xf_CreateSurface(RdpgfxClientContext* context, RDPGFX_CREATE_SURFACE_PDU* c if (!surface->data) { - free (surface); + free(surface); return CHANNEL_RC_NO_MEMORY; } @@ -743,8 +747,8 @@ UINT xf_CreateSurface(RdpgfxClientContext* context, RDPGFX_CREATE_SURFACE_PDU* c if (!surface->stage) { - free (surface->data); - free (surface); + free(surface->data); + free(surface); return CHANNEL_RC_NO_MEMORY; } @@ -770,8 +774,8 @@ UINT xf_CreateSurface(RdpgfxClientContext* context, RDPGFX_CREATE_SURFACE_PDU* c */ UINT xf_DeleteSurface(RdpgfxClientContext* context, RDPGFX_DELETE_SURFACE_PDU* deleteSurface) { + rdpCodecs* codecs = NULL; xfGfxSurface* surface = NULL; - xfContext* xfc = (xfContext*) context->custom; surface = (xfGfxSurface*) context->GetSurfaceData(context, deleteSurface->surfaceId); @@ -781,13 +785,16 @@ UINT xf_DeleteSurface(RdpgfxClientContext* context, RDPGFX_DELETE_SURFACE_PDU* d _aligned_free(surface->data); _aligned_free(surface->stage); region16_uninit(&surface->invalidRegion); + codecs = surface->codecs; free(surface); } context->SetSurfaceData(context, deleteSurface->surfaceId, NULL); - if (xfc->codecs->progressive) - progressive_delete_surface_context(xfc->codecs->progressive, deleteSurface->surfaceId); + if (codecs && codecs->progressive) + progressive_delete_surface_context(codecs->progressive, deleteSurface->surfaceId); + + codecs_free(codecs); return CHANNEL_RC_OK; } @@ -947,7 +954,7 @@ UINT xf_SurfaceToCache(RdpgfxClientContext* context, RDPGFX_SURFACE_TO_CACHE_PDU if (!cacheEntry->data) { - free (cacheEntry); + free(cacheEntry); return CHANNEL_RC_NO_MEMORY; } diff --git a/client/X11/xf_gfx.h b/client/X11/xf_gfx.h index 6748d6a..423b335 100644 --- a/client/X11/xf_gfx.h +++ b/client/X11/xf_gfx.h @@ -28,6 +28,7 @@ struct xf_gfx_surface { UINT16 surfaceId; + rdpCodecs* codecs; UINT32 width; UINT32 height; BOOL alpha; diff --git a/libfreerdp/core/codecs.c b/libfreerdp/core/codecs.c index 21d5d96..31cdbcd 100644 --- a/libfreerdp/core/codecs.c +++ b/libfreerdp/core/codecs.c @@ -29,7 +29,7 @@ BOOL freerdp_client_codecs_prepare(rdpCodecs* codecs, UINT32 flags) { - if (flags & FREERDP_CODEC_INTERLEAVED && !codecs->interleaved) + if ((flags & FREERDP_CODEC_INTERLEAVED) && !codecs->interleaved) { if (!(codecs->interleaved = bitmap_interleaved_context_new(FALSE))) { @@ -38,7 +38,7 @@ BOOL freerdp_client_codecs_prepare(rdpCodecs* codecs, UINT32 flags) } } - if (flags & FREERDP_CODEC_PLANAR && !codecs->planar) + if ((flags & FREERDP_CODEC_PLANAR) && !codecs->planar) { if (!(codecs->planar = freerdp_bitmap_planar_context_new(FALSE, 64, 64))) { @@ -47,7 +47,7 @@ BOOL freerdp_client_codecs_prepare(rdpCodecs* codecs, UINT32 flags) } } - if (flags & FREERDP_CODEC_NSCODEC && !codecs->nsc) + if ((flags & FREERDP_CODEC_NSCODEC) && !codecs->nsc) { if (!(codecs->nsc = nsc_context_new())) { @@ -56,7 +56,7 @@ BOOL freerdp_client_codecs_prepare(rdpCodecs* codecs, UINT32 flags) } } - if (flags & FREERDP_CODEC_REMOTEFX && !codecs->rfx) + if ((flags & FREERDP_CODEC_REMOTEFX) && !codecs->rfx) { if (!(codecs->rfx = rfx_context_new(FALSE))) { @@ -65,7 +65,7 @@ BOOL freerdp_client_codecs_prepare(rdpCodecs* codecs, UINT32 flags) } } - if (flags & FREERDP_CODEC_CLEARCODEC && !codecs->clear) + if ((flags & FREERDP_CODEC_CLEARCODEC) && !codecs->clear) { if (!(codecs->clear = clear_context_new(FALSE))) { @@ -79,7 +79,7 @@ BOOL freerdp_client_codecs_prepare(rdpCodecs* codecs, UINT32 flags) } - if (flags & FREERDP_CODEC_PROGRESSIVE && !codecs->progressive) + if ((flags & FREERDP_CODEC_PROGRESSIVE) && !codecs->progressive) { if (!(codecs->progressive = progressive_context_new(FALSE))) { @@ -88,7 +88,7 @@ BOOL freerdp_client_codecs_prepare(rdpCodecs* codecs, UINT32 flags) } } - if (flags & FREERDP_CODEC_H264 && !codecs->h264) + if ((flags & FREERDP_CODEC_H264) && !codecs->h264) { if (!(codecs->h264 = h264_context_new(FALSE))) { -- 2.7.4