Fixed wayland buffer updates

The wayland buffer size always matches the current window size.
That might be different from the actual remote framebuffer size,
to when copying always use the correct strides to avoid distorted
screen content.
This commit is contained in:
Armin Novak 2019-01-24 15:10:08 +01:00
parent 0fd27e0e38
commit 823411c2f3
3 changed files with 45 additions and 7 deletions

View File

@ -60,8 +60,12 @@ static BOOL wl_update_buffer(wlfContext* context_w, INT32 ix, INT32 iy, INT32 iw
{
rdpGdi* gdi;
char* data;
size_t baseOffset;
size_t baseSrcOffset;
size_t baseDstOffset;
UINT32 i, x, y, w, h;
UwacSize geometry;
size_t stride;
UwacReturnCode rc;
if (!context_w)
return FALSE;
@ -73,9 +77,10 @@ static BOOL wl_update_buffer(wlfContext* context_w, INT32 ix, INT32 iy, INT32 iw
y = (UINT32)iy;
w = (UINT32)iw;
h = (UINT32)ih;
rc = UwacWindowGetDrawingBufferGeometry(context_w->window, &geometry, &stride);
data = UwacWindowGetDrawingBuffer(context_w->window);
if (!data)
if (!data || (rc != UWAC_SUCCESS))
return FALSE;
gdi = context_w->context.gdi;
@ -83,12 +88,19 @@ static BOOL wl_update_buffer(wlfContext* context_w, INT32 ix, INT32 iy, INT32 iw
if (!gdi)
return FALSE;
baseOffset = y * gdi->stride + x * GetBytesPerPixel(gdi->dstFormat);
for (i = 0; i < h; i++)
/* Ignore output if the surface size does not match. */
if ((x > geometry.width) || (y > geometry.height))
return TRUE;
baseSrcOffset = y * gdi->stride + x * GetBytesPerPixel(gdi->dstFormat);
baseDstOffset = y * stride + x * 4;
for (i = 0; i < MIN(h, geometry.height - y); i++)
{
size_t offset = i * gdi->stride + baseOffset;
memcpy(data + offset, gdi->primary_buffer + offset,
w * GetBytesPerPixel(gdi->dstFormat));
const size_t srcOffset = i * gdi->stride + baseSrcOffset;
const size_t dstOffset = i * stride + baseDstOffset;
memcpy(data + dstOffset, gdi->primary_buffer + srcOffset,
MIN(w, geometry.width - x) * GetBytesPerPixel(gdi->dstFormat));
}
if (UwacWindowAddDamage(context_w->window, x, y, w, h) != UWAC_SUCCESS)

View File

@ -453,6 +453,16 @@ UWAC_API void* UwacWindowGetDrawingBuffer(UwacWindow* window);
UWAC_API UwacReturnCode UwacWindowAddDamage(UwacWindow* window, uint32_t x, uint32_t y,
uint32_t width, uint32_t height);
/**
* returns the geometry of the given UwacWindow buffer
*
* @param window the UwacWindow
* @param geometry the geometry to fill
* @param stride the length of a buffer line in bytes
* @return UWAC_SUCCESS on success, an Uwac error otherwise
*/
UWAC_API UwacReturnCode UwacWindowGetDrawingBufferGeometry(UwacWindow* window, UwacSize* geometry, size_t* stride);
/**
* Sends a frame to the compositor with the content of the drawing buffer
*

View File

@ -670,6 +670,22 @@ UwacReturnCode UwacWindowAddDamage(UwacWindow* window, uint32_t x, uint32_t y, u
return UWAC_SUCCESS;
}
UwacReturnCode UwacWindowGetDrawingBufferGeometry(UwacWindow* window, UwacSize* geometry, size_t* stride)
{
if (!window || !window->drawingBuffer)
return UWAC_ERROR_INTERNAL;
if (geometry)
{
geometry->width = window->width;
geometry->height = window->height;
}
if (stride)
*stride = window->stride;
return UWAC_SUCCESS;
}
UwacReturnCode UwacWindowSubmitBuffer(UwacWindow* window, bool copyContentForNextFrame)
{