Merge pull request #6284 from akallabeth/wayland
Lock wayland buffer updates
This commit is contained in:
commit
152bf0cda4
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user