Fixed alignment requirements for surface sizes.
authorArmin Novak <armin.novak@thincast.com>
Wed, 8 May 2019 08:32:01 +0000 (10:32 +0200)
committerArmin Novak <armin.novak@thincast.com>
Wed, 8 May 2019 08:36:00 +0000 (10:36 +0200)
client/X11/xf_channels.c
client/X11/xf_gfx.c
client/X11/xf_gfx.h
include/freerdp/gdi/gfx.h
libfreerdp/gdi/gfx.c

index ef91504..228c7c3 100644 (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)
        {
index 2783e17..90f417e 100644 (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);
        }
 
@@ -401,18 +408,15 @@ 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)
index 44f72af..8c6f56a 100644 (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 */
index 3e6e654..9ba087c 100644 (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;
index 7828042..17e6643 100644 (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,