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

View File

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

View File

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