Merge pull request #6284 from akallabeth/wayland

Lock wayland buffer updates
This commit is contained in:
Martin Fleisz 2020-06-19 11:44:28 +02:00 committed by GitHub
commit 152bf0cda4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 87 additions and 39 deletions

View File

@ -62,6 +62,7 @@ static BOOL wl_begin_paint(rdpContext* context)
static BOOL wl_update_buffer(wlfContext* context_w, INT32 ix, INT32 iy, INT32 iw, INT32 ih)
{
BOOL res = FALSE;
rdpGdi* gdi;
char* data;
UINT32 x, y, w, h;
@ -76,6 +77,7 @@ static BOOL wl_update_buffer(wlfContext* context_w, INT32 ix, INT32 iy, INT32 iw
if ((ix < 0) || (iy < 0) || (iw < 0) || (ih < 0))
return FALSE;
EnterCriticalSection(&context_w->critical);
x = (UINT32)ix;
y = (UINT32)iy;
w = (UINT32)iw;
@ -84,16 +86,19 @@ static BOOL wl_update_buffer(wlfContext* context_w, INT32 ix, INT32 iy, INT32 iw
data = UwacWindowGetDrawingBuffer(context_w->window);
if (!data || (rc != UWAC_SUCCESS))
return FALSE;
goto fail;
gdi = context_w->context.gdi;
if (!gdi)
return FALSE;
goto fail;
/* Ignore output if the surface size does not match. */
if (((INT64)x > geometry.width) || ((INT64)y > geometry.height))
return TRUE;
{
res = TRUE;
goto fail;
}
area.left = x;
area.top = y;
@ -103,21 +108,24 @@ static BOOL wl_update_buffer(wlfContext* context_w, INT32 ix, INT32 iy, INT32 iw
if (!wlf_copy_image(gdi->primary_buffer, gdi->stride, gdi->width, gdi->height, data, stride,
geometry.width, geometry.height, &area,
context_w->context.settings->SmartSizing))
return FALSE;
goto fail;
if (!wlf_scale_coordinates(&context_w->context, &x, &y, FALSE))
return FALSE;
goto fail;
if (!wlf_scale_coordinates(&context_w->context, &w, &h, FALSE))
return FALSE;
goto fail;
if (UwacWindowAddDamage(context_w->window, x, y, w, h) != UWAC_SUCCESS)
return FALSE;
goto fail;
if (UwacWindowSubmitBuffer(context_w->window, false) != UWAC_SUCCESS)
return FALSE;
goto fail;
return TRUE;
res = TRUE;
fail:
LeaveCriticalSection(&context_w->critical);
return res;
}
static BOOL wl_end_paint(rdpContext* context)
@ -296,6 +304,7 @@ static void wl_post_disconnect(freerdp* instance)
static BOOL handle_uwac_events(freerdp* instance, UwacDisplay* display)
{
BOOL rc;
UwacEvent event;
wlfContext* context;
@ -321,9 +330,11 @@ static BOOL handle_uwac_events(freerdp* instance, UwacDisplay* display)
break;
case UWAC_EVENT_FRAME_DONE:
if (UwacWindowSubmitBuffer(context->window, false) != UWAC_SUCCESS)
EnterCriticalSection(&context->critical);
rc = UwacWindowSubmitBuffer(context->window, false);
LeaveCriticalSection(&context->critical);
if (rc != UWAC_SUCCESS)
return FALSE;
break;
case UWAC_EVENT_POINTER_ENTER:
@ -552,6 +563,8 @@ static BOOL wlf_client_new(freerdp* instance, rdpContext* context)
if (!wfl->displayHandle)
return FALSE;
InitializeCriticalSection(&wfl->critical);
return TRUE;
}
@ -567,6 +580,7 @@ static void wlf_client_free(freerdp* instance, rdpContext* context)
if (wlf->displayHandle)
CloseHandle(wlf->displayHandle);
DeleteCriticalSection(&wlf->critical);
}
static int wfl_client_start(rdpContext* context)

View File

@ -50,6 +50,7 @@ struct wlf_context
wfClipboard* clipboard;
wlfDispContext* disp;
wLog* log;
CRITICAL_SECTION critical;
};
BOOL wlf_scale_coordinates(rdpContext* context, UINT32* px, UINT32* py, BOOL fromLocalToRDP);

View File

@ -235,7 +235,8 @@ struct uwac_window
struct wl_region* opaque_region;
struct wl_region* input_region;
UwacBuffer *drawingBuffer, *pendingBuffer;
SSIZE_T drawingBufferIdx;
SSIZE_T pendingBufferIdx;
struct wl_surface* surface;
struct wl_shell_surface* shell_surface;
struct xdg_surface* xdg_surface;

View File

@ -136,13 +136,13 @@ static void xdg_handle_toplevel_configure(void* data, struct xdg_toplevel* xdg_t
{
assert(
uwacErrorHandler(window->display, ret, "failed to reallocate a wayland buffers\n"));
window->drawingBuffer = window->pendingBuffer = NULL;
window->drawingBufferIdx = window->pendingBufferIdx = -1;
return;
}
window->drawingBuffer = &window->buffers[0];
if (window->pendingBuffer != NULL)
window->pendingBuffer = window->drawingBuffer;
window->drawingBufferIdx = 0;
if (window->pendingBufferIdx != -1)
window->pendingBufferIdx = window->drawingBufferIdx;
}
else
{
@ -219,13 +219,13 @@ static void ivi_handle_configure(void* data, struct ivi_surface* surface, int32_
{
assert(
uwacErrorHandler(window->display, ret, "failed to reallocate a wayland buffers\n"));
window->drawingBuffer = window->pendingBuffer = NULL;
window->drawingBufferIdx = window->pendingBufferIdx = -1;
return;
}
window->drawingBuffer = &window->buffers[0];
if (window->pendingBuffer != NULL)
window->pendingBuffer = window->drawingBuffer;
window->drawingBufferIdx = 0;
if (window->pendingBufferIdx != -1)
window->pendingBufferIdx = window->drawingBufferIdx;
}
else
{
@ -277,13 +277,13 @@ static void shell_configure(void* data, struct wl_shell_surface* surface, uint32
{
assert(
uwacErrorHandler(window->display, ret, "failed to reallocate a wayland buffers\n"));
window->drawingBuffer = window->pendingBuffer = NULL;
window->drawingBufferIdx = window->pendingBufferIdx = -1;
return;
}
window->drawingBuffer = &window->buffers[0];
if (window->pendingBuffer != NULL)
window->pendingBuffer = window->drawingBuffer;
window->drawingBufferIdx = 0;
if (window->pendingBufferIdx != -1)
window->pendingBufferIdx = window->drawingBufferIdx;
}
else
{
@ -364,15 +364,21 @@ error_mmap:
return ret;
}
static UwacBuffer* UwacWindowFindFreeBuffer(UwacWindow* w)
static UwacBuffer* UwacWindowFindFreeBuffer(UwacWindow* w, SSIZE_T* index)
{
int i, ret;
SSIZE_T i;
int ret;
if (index)
*index = -1;
for (i = 0; i < w->nbuffers; i++)
{
if (!w->buffers[i].used)
{
w->buffers[i].used = true;
if (index)
*index = i;
return &w->buffers[i];
}
}
@ -386,6 +392,8 @@ static UwacBuffer* UwacWindowFindFreeBuffer(UwacWindow* w)
}
w->buffers[i].used = true;
if (index)
*index = i;
return &w->buffers[i];
}
@ -457,7 +465,8 @@ UwacWindow* UwacCreateWindowShm(UwacDisplay* display, uint32_t width, uint32_t h
}
w->buffers[0].used = true;
w->drawingBuffer = &w->buffers[0];
w->drawingBufferIdx = 0;
w->pendingBufferIdx = -1;
w->surface = wl_compositor_create_surface(display->compositor);
if (!w->surface)
@ -603,7 +612,16 @@ UwacReturnCode UwacWindowSetInputRegion(UwacWindow* window, uint32_t x, uint32_t
void* UwacWindowGetDrawingBuffer(UwacWindow* window)
{
return window->drawingBuffer->data;
UwacBuffer* buffer;
if (window->drawingBufferIdx < 0)
return NULL;
buffer = &window->buffers[window->drawingBufferIdx];
if (!buffer)
return NULL;
return buffer->data;
}
static void frame_done_cb(void* data, struct wl_callback* callback, uint32_t time);
@ -654,7 +672,7 @@ static void frame_done_cb(void* data, struct wl_callback* callback, uint32_t tim
UwacFrameDoneEvent* event;
wl_callback_destroy(callback);
window->pendingBuffer = NULL;
window->pendingBufferIdx = -1;
event = (UwacFrameDoneEvent*)UwacDisplayNewEvent(window->display, UWAC_EVENT_FRAME_DONE);
if (event)
@ -677,13 +695,20 @@ UwacReturnCode UwacWindowAddDamage(UwacWindow* window, uint32_t x, uint32_t y, u
uint32_t height)
{
RECTANGLE_16 box;
UwacBuffer* buf;
box.left = x;
box.top = y;
box.right = x + width;
box.bottom = y + height;
UwacBuffer* buf = window->drawingBuffer;
if (window->drawingBufferIdx < 0)
return UWAC_ERROR_INTERNAL;
buf = &window->buffers[window->drawingBufferIdx];
if (!buf)
return UWAC_ERROR_INTERNAL;
if (!region16_union_rect(&buf->damage, &buf->damage, &box))
return UWAC_ERROR_INTERNAL;
@ -695,7 +720,7 @@ UwacReturnCode UwacWindowAddDamage(UwacWindow* window, uint32_t x, uint32_t y, u
UwacReturnCode UwacWindowGetDrawingBufferGeometry(UwacWindow* window, UwacSize* geometry,
size_t* stride)
{
if (!window || !window->drawingBuffer)
if (!window || (window->drawingBufferIdx < 0))
return UWAC_ERROR_INTERNAL;
if (geometry)
@ -712,22 +737,29 @@ UwacReturnCode UwacWindowGetDrawingBufferGeometry(UwacWindow* window, UwacSize*
UwacReturnCode UwacWindowSubmitBuffer(UwacWindow* window, bool copyContentForNextFrame)
{
UwacBuffer* drawingBuffer = window->drawingBuffer;
UwacBuffer* currentDrawingBuffer;
UwacBuffer* nextDrawingBuffer;
UwacBuffer* pendingBuffer;
if (window->pendingBuffer || !drawingBuffer->dirty)
if (window->drawingBufferIdx < 0)
return UWAC_ERROR_INTERNAL;
currentDrawingBuffer = &window->buffers[window->drawingBufferIdx];
if ((window->pendingBufferIdx >= 0) || !currentDrawingBuffer->dirty)
return UWAC_SUCCESS;
window->pendingBuffer = drawingBuffer;
window->drawingBuffer = UwacWindowFindFreeBuffer(window);
window->pendingBufferIdx = window->drawingBufferIdx;
nextDrawingBuffer = UwacWindowFindFreeBuffer(window, &window->drawingBufferIdx);
pendingBuffer = &window->buffers[window->pendingBufferIdx];
if (!window->drawingBuffer)
if ((!nextDrawingBuffer) || (window->drawingBufferIdx < 0))
return UWAC_ERROR_NOMEMORY;
if (copyContentForNextFrame)
memcpy(window->drawingBuffer->data, window->pendingBuffer->data,
window->stride * window->height);
memcpy(nextDrawingBuffer->data, pendingBuffer->data, window->stride * window->height);
UwacSubmitBufferPtr(window, drawingBuffer);
UwacSubmitBufferPtr(window, pendingBuffer);
return UWAC_SUCCESS;
}