Fixed alignment requirements for surface sizes.

This commit is contained in:
Armin Novak 2019-05-08 10:32:01 +02:00
parent 1bb933b991
commit 3d1cec894c
5 changed files with 48 additions and 47 deletions

View File

@ -49,10 +49,7 @@ void xf_OnChannelConnectedEventHandler(void* context, ChannelConnectedEventArgs*
}
else if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0)
{
if (settings->SoftwareGdi)
gdi_graphics_pipeline_init(xfc->context.gdi, (RdpgfxClientContext*) e->pInterface);
else
xf_graphics_pipeline_init(xfc, (RdpgfxClientContext*) e->pInterface);
xf_graphics_pipeline_init(xfc, (RdpgfxClientContext*) e->pInterface);
}
else if (strcmp(e->name, RAIL_SVC_CHANNEL_NAME) == 0)
{
@ -106,10 +103,7 @@ void xf_OnChannelDisconnectedEventHandler(void* context, ChannelDisconnectedEven
}
else if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0)
{
if (settings->SoftwareGdi)
gdi_graphics_pipeline_uninit(xfc->context.gdi, (RdpgfxClientContext*) e->pInterface);
else
xf_graphics_pipeline_uninit(xfc, (RdpgfxClientContext*) e->pInterface);
xf_graphics_pipeline_uninit(xfc, (RdpgfxClientContext*) e->pInterface);
}
else if (strcmp(e->name, RAIL_SVC_CHANNEL_NAME) == 0)
{

View File

@ -45,15 +45,15 @@ static UINT xf_OutputUpdate(xfContext* xfc, xfGfxSurface* surface)
surfaceY = surface->gdi.outputOriginY;
surfaceRect.left = 0;
surfaceRect.top = 0;
surfaceRect.right = surface->gdi.width;
surfaceRect.bottom = surface->gdi.height;
surfaceRect.right = surface->gdi.mappedWidth;
surfaceRect.bottom = surface->gdi.mappedHeight;
XSetClipMask(xfc->display, xfc->gc, None);
XSetFunction(xfc->display, xfc->gc, GXcopy);
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;
sx = surface->gdi.outputTargetWidth / (double)surface->gdi.mappedWidth;
sy = surface->gdi.outputTargetHeight / (double)surface->gdi.mappedHeight;
if (!(rects = region16_rects(&surface->gdi.invalidRegion, &nbRects)))
return CHANNEL_RC_OK;
@ -143,9 +143,12 @@ static UINT xf_UpdateSurfaces(RdpgfxClientContext* context)
if (!surface)
continue;
/* Already handled in UpdateSurfaceArea callbacks */
if (surface->gdi.windowId != 0)
continue;
/* If UpdateSurfaceArea callback is available, the output has already been updated. */
if (context->UpdateSurfaceArea)
{
if (surface->gdi.windowId != 0)
continue;
}
status = ERROR_INTERNAL_ERROR;
@ -267,8 +270,12 @@ static UINT xf_CreateSurface(RdpgfxClientContext* context,
}
surface->gdi.surfaceId = createSurface->surfaceId;
surface->gdi.width = (UINT32) createSurface->width;
surface->gdi.height = (UINT32) createSurface->height;
surface->gdi.width = x11_pad_scanline(createSurface->width, 0);
surface->gdi.height = x11_pad_scanline(createSurface->height, 0);
surface->gdi.mappedWidth = createSurface->width;
surface->gdi.mappedHeight = createSurface->height;
surface->gdi.outputTargetWidth = createSurface->width;
surface->gdi.outputTargetHeight = createSurface->height;
switch (createSurface->pixelFormat)
{
@ -302,7 +309,7 @@ static UINT xf_CreateSurface(RdpgfxClientContext* context,
if (AreColorFormatsEqualNoAlpha(gdi->dstFormat, surface->gdi.format))
{
surface->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0,
(char*) surface->gdi.data, surface->gdi.width, surface->gdi.height,
(char*) surface->gdi.data, surface->gdi.mappedWidth, surface->gdi.mappedHeight,
xfc->scanline_pad, surface->gdi.scanline);
}
else
@ -323,7 +330,7 @@ static UINT xf_CreateSurface(RdpgfxClientContext* context,
ZeroMemory(surface->stage, size);
surface->image = XCreateImage(xfc->display, xfc->visual, xfc->depth,
ZPixmap, 0, (char*) surface->stage,
surface->gdi.width, surface->gdi.height,
surface->gdi.mappedWidth, surface->gdi.mappedHeight,
xfc->scanline_pad, surface->stageScanline);
}
@ -400,19 +407,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_ex(gdi, gfx, map, unmap, update);
gfx->UpdateSurfaces = xf_UpdateSurfaces;
gfx->CreateSurface = xf_CreateSurface;
gfx->DeleteSurface = xf_DeleteSurface;
gdi_graphics_pipeline_init(gdi, gfx);
if (!xfc->context.settings->SoftwareGdi)
{
gfx->UpdateSurfaces = xf_UpdateSurfaces;
gfx->CreateSurface = xf_CreateSurface;
gfx->DeleteSurface = xf_DeleteSurface;
}
}
void xf_graphics_pipeline_uninit(xfContext* xfc, RdpgfxClientContext* gfx)

View File

@ -51,10 +51,7 @@ 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

@ -30,6 +30,8 @@ struct gdi_gfx_surface
H264_CONTEXT* h264;
UINT32 width;
UINT32 height;
UINT32 mappedWidth;
UINT32 mappedHeight;
BYTE* data;
UINT32 scanline;
UINT32 format;

View File

@ -31,7 +31,7 @@
static DWORD gfx_align_scanline(DWORD widthInBytes, DWORD alignment)
{
const UINT32 align = 16;
const UINT32 align = alignment;
const UINT32 pad = align - (widthInBytes % alignment);
UINT32 scanline = widthInBytes;
@ -114,12 +114,12 @@ static UINT gdi_OutputUpdate(rdpGdi* gdi, gdiGfxSurface* surface)
surfaceY = surface->outputOriginY;
surfaceRect.left = 0;
surfaceRect.top = 0;
surfaceRect.right = surface->width;
surfaceRect.bottom = surface->height;
surfaceRect.right = surface->mappedWidth;
surfaceRect.bottom = surface->mappedHeight;
region16_intersect_rect(&(surface->invalidRegion),
&(surface->invalidRegion), &surfaceRect);
sx = surface->outputTargetWidth / (double)surface->width;
sy = surface->outputTargetHeight / (double)surface->height;
sx = surface->outputTargetWidth / (double)surface->mappedWidth;
sy = surface->outputTargetHeight / (double)surface->mappedHeight;
if (!(rects = region16_rects(&surface->invalidRegion, &nbRects)) || !nbRects)
return CHANNEL_RC_OK;
@ -969,8 +969,12 @@ static UINT gdi_CreateSurface(RdpgfxClientContext* context,
}
surface->surfaceId = createSurface->surfaceId;
surface->width = (UINT32) createSurface->width;
surface->height = (UINT32) createSurface->height;
surface->width = gfx_align_scanline(createSurface->width, 16);
surface->height = gfx_align_scanline(createSurface->height, 16);
surface->mappedWidth = createSurface->width;
surface->mappedHeight = createSurface->height;
surface->outputTargetWidth = createSurface->width;
surface->outputTargetHeight = createSurface->height;
switch (createSurface->pixelFormat)
{
@ -1354,8 +1358,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;
surface->outputTargetWidth = surface->mappedWidth;
surface->outputTargetHeight = surface->mappedHeight;
region16_clear(&surface->invalidRegion);
rc = CHANNEL_RC_OK;
fail:
@ -1411,8 +1415,8 @@ static UINT gdi_MapSurfaceToWindow(RdpgfxClientContext* context,
}
surface->windowId = surfaceToWindow->windowId;
surface->width = surfaceToWindow->mappedWidth;
surface->height = surfaceToWindow->mappedHeight;
surface->mappedWidth = surfaceToWindow->mappedWidth;
surface->mappedHeight = surfaceToWindow->mappedHeight;
surface->outputTargetWidth = surfaceToWindow->mappedWidth;
surface->outputTargetHeight = surfaceToWindow->mappedHeight;
rc = IFCALLRESULT(CHANNEL_RC_OK, context->MapWindowForSurface, context,
@ -1442,8 +1446,8 @@ static UINT gdi_MapSurfaceToScaledWindow(RdpgfxClientContext* context,
}
surface->windowId = surfaceToWindow->windowId;
surface->width = surfaceToWindow->mappedWidth;
surface->height = surfaceToWindow->mappedHeight;
surface->mappedWidth = surfaceToWindow->mappedWidth;
surface->mappedHeight = surfaceToWindow->mappedHeight;
surface->outputTargetWidth = surfaceToWindow->targetWidth;
surface->outputTargetHeight = surfaceToWindow->targetHeight;
rc = IFCALLRESULT(CHANNEL_RC_OK, context->MapWindowForSurface, context,