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)
|
static BOOL wl_update_buffer(wlfContext* context_w, INT32 ix, INT32 iy, INT32 iw, INT32 ih)
|
||||||
{
|
{
|
||||||
|
BOOL res = FALSE;
|
||||||
rdpGdi* gdi;
|
rdpGdi* gdi;
|
||||||
char* data;
|
char* data;
|
||||||
UINT32 x, y, w, h;
|
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))
|
if ((ix < 0) || (iy < 0) || (iw < 0) || (ih < 0))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
EnterCriticalSection(&context_w->critical);
|
||||||
x = (UINT32)ix;
|
x = (UINT32)ix;
|
||||||
y = (UINT32)iy;
|
y = (UINT32)iy;
|
||||||
w = (UINT32)iw;
|
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);
|
data = UwacWindowGetDrawingBuffer(context_w->window);
|
||||||
|
|
||||||
if (!data || (rc != UWAC_SUCCESS))
|
if (!data || (rc != UWAC_SUCCESS))
|
||||||
return FALSE;
|
goto fail;
|
||||||
|
|
||||||
gdi = context_w->context.gdi;
|
gdi = context_w->context.gdi;
|
||||||
|
|
||||||
if (!gdi)
|
if (!gdi)
|
||||||
return FALSE;
|
goto fail;
|
||||||
|
|
||||||
/* Ignore output if the surface size does not match. */
|
/* Ignore output if the surface size does not match. */
|
||||||
if (((INT64)x > geometry.width) || ((INT64)y > geometry.height))
|
if (((INT64)x > geometry.width) || ((INT64)y > geometry.height))
|
||||||
return TRUE;
|
{
|
||||||
|
res = TRUE;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
area.left = x;
|
area.left = x;
|
||||||
area.top = y;
|
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,
|
if (!wlf_copy_image(gdi->primary_buffer, gdi->stride, gdi->width, gdi->height, data, stride,
|
||||||
geometry.width, geometry.height, &area,
|
geometry.width, geometry.height, &area,
|
||||||
context_w->context.settings->SmartSizing))
|
context_w->context.settings->SmartSizing))
|
||||||
return FALSE;
|
goto fail;
|
||||||
|
|
||||||
if (!wlf_scale_coordinates(&context_w->context, &x, &y, FALSE))
|
if (!wlf_scale_coordinates(&context_w->context, &x, &y, FALSE))
|
||||||
return FALSE;
|
goto fail;
|
||||||
|
|
||||||
if (!wlf_scale_coordinates(&context_w->context, &w, &h, FALSE))
|
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)
|
if (UwacWindowAddDamage(context_w->window, x, y, w, h) != UWAC_SUCCESS)
|
||||||
return FALSE;
|
goto fail;
|
||||||
|
|
||||||
if (UwacWindowSubmitBuffer(context_w->window, false) != UWAC_SUCCESS)
|
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)
|
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)
|
static BOOL handle_uwac_events(freerdp* instance, UwacDisplay* display)
|
||||||
{
|
{
|
||||||
|
BOOL rc;
|
||||||
UwacEvent event;
|
UwacEvent event;
|
||||||
wlfContext* context;
|
wlfContext* context;
|
||||||
|
|
||||||
@ -321,9 +330,11 @@ static BOOL handle_uwac_events(freerdp* instance, UwacDisplay* display)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case UWAC_EVENT_FRAME_DONE:
|
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;
|
return FALSE;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UWAC_EVENT_POINTER_ENTER:
|
case UWAC_EVENT_POINTER_ENTER:
|
||||||
@ -552,6 +563,8 @@ static BOOL wlf_client_new(freerdp* instance, rdpContext* context)
|
|||||||
if (!wfl->displayHandle)
|
if (!wfl->displayHandle)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
InitializeCriticalSection(&wfl->critical);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -567,6 +580,7 @@ static void wlf_client_free(freerdp* instance, rdpContext* context)
|
|||||||
|
|
||||||
if (wlf->displayHandle)
|
if (wlf->displayHandle)
|
||||||
CloseHandle(wlf->displayHandle);
|
CloseHandle(wlf->displayHandle);
|
||||||
|
DeleteCriticalSection(&wlf->critical);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wfl_client_start(rdpContext* context)
|
static int wfl_client_start(rdpContext* context)
|
||||||
|
@ -50,6 +50,7 @@ struct wlf_context
|
|||||||
wfClipboard* clipboard;
|
wfClipboard* clipboard;
|
||||||
wlfDispContext* disp;
|
wlfDispContext* disp;
|
||||||
wLog* log;
|
wLog* log;
|
||||||
|
CRITICAL_SECTION critical;
|
||||||
};
|
};
|
||||||
|
|
||||||
BOOL wlf_scale_coordinates(rdpContext* context, UINT32* px, UINT32* py, BOOL fromLocalToRDP);
|
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* opaque_region;
|
||||||
struct wl_region* input_region;
|
struct wl_region* input_region;
|
||||||
UwacBuffer *drawingBuffer, *pendingBuffer;
|
SSIZE_T drawingBufferIdx;
|
||||||
|
SSIZE_T pendingBufferIdx;
|
||||||
struct wl_surface* surface;
|
struct wl_surface* surface;
|
||||||
struct wl_shell_surface* shell_surface;
|
struct wl_shell_surface* shell_surface;
|
||||||
struct xdg_surface* xdg_surface;
|
struct xdg_surface* xdg_surface;
|
||||||
|
@ -136,13 +136,13 @@ static void xdg_handle_toplevel_configure(void* data, struct xdg_toplevel* xdg_t
|
|||||||
{
|
{
|
||||||
assert(
|
assert(
|
||||||
uwacErrorHandler(window->display, ret, "failed to reallocate a wayland buffers\n"));
|
uwacErrorHandler(window->display, ret, "failed to reallocate a wayland buffers\n"));
|
||||||
window->drawingBuffer = window->pendingBuffer = NULL;
|
window->drawingBufferIdx = window->pendingBufferIdx = -1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window->drawingBuffer = &window->buffers[0];
|
window->drawingBufferIdx = 0;
|
||||||
if (window->pendingBuffer != NULL)
|
if (window->pendingBufferIdx != -1)
|
||||||
window->pendingBuffer = window->drawingBuffer;
|
window->pendingBufferIdx = window->drawingBufferIdx;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -219,13 +219,13 @@ static void ivi_handle_configure(void* data, struct ivi_surface* surface, int32_
|
|||||||
{
|
{
|
||||||
assert(
|
assert(
|
||||||
uwacErrorHandler(window->display, ret, "failed to reallocate a wayland buffers\n"));
|
uwacErrorHandler(window->display, ret, "failed to reallocate a wayland buffers\n"));
|
||||||
window->drawingBuffer = window->pendingBuffer = NULL;
|
window->drawingBufferIdx = window->pendingBufferIdx = -1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window->drawingBuffer = &window->buffers[0];
|
window->drawingBufferIdx = 0;
|
||||||
if (window->pendingBuffer != NULL)
|
if (window->pendingBufferIdx != -1)
|
||||||
window->pendingBuffer = window->drawingBuffer;
|
window->pendingBufferIdx = window->drawingBufferIdx;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -277,13 +277,13 @@ static void shell_configure(void* data, struct wl_shell_surface* surface, uint32
|
|||||||
{
|
{
|
||||||
assert(
|
assert(
|
||||||
uwacErrorHandler(window->display, ret, "failed to reallocate a wayland buffers\n"));
|
uwacErrorHandler(window->display, ret, "failed to reallocate a wayland buffers\n"));
|
||||||
window->drawingBuffer = window->pendingBuffer = NULL;
|
window->drawingBufferIdx = window->pendingBufferIdx = -1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window->drawingBuffer = &window->buffers[0];
|
window->drawingBufferIdx = 0;
|
||||||
if (window->pendingBuffer != NULL)
|
if (window->pendingBufferIdx != -1)
|
||||||
window->pendingBuffer = window->drawingBuffer;
|
window->pendingBufferIdx = window->drawingBufferIdx;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -364,15 +364,21 @@ error_mmap:
|
|||||||
return ret;
|
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++)
|
for (i = 0; i < w->nbuffers; i++)
|
||||||
{
|
{
|
||||||
if (!w->buffers[i].used)
|
if (!w->buffers[i].used)
|
||||||
{
|
{
|
||||||
w->buffers[i].used = true;
|
w->buffers[i].used = true;
|
||||||
|
if (index)
|
||||||
|
*index = i;
|
||||||
return &w->buffers[i];
|
return &w->buffers[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -386,6 +392,8 @@ static UwacBuffer* UwacWindowFindFreeBuffer(UwacWindow* w)
|
|||||||
}
|
}
|
||||||
|
|
||||||
w->buffers[i].used = true;
|
w->buffers[i].used = true;
|
||||||
|
if (index)
|
||||||
|
*index = i;
|
||||||
return &w->buffers[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->buffers[0].used = true;
|
||||||
w->drawingBuffer = &w->buffers[0];
|
w->drawingBufferIdx = 0;
|
||||||
|
w->pendingBufferIdx = -1;
|
||||||
w->surface = wl_compositor_create_surface(display->compositor);
|
w->surface = wl_compositor_create_surface(display->compositor);
|
||||||
|
|
||||||
if (!w->surface)
|
if (!w->surface)
|
||||||
@ -603,7 +612,16 @@ UwacReturnCode UwacWindowSetInputRegion(UwacWindow* window, uint32_t x, uint32_t
|
|||||||
|
|
||||||
void* UwacWindowGetDrawingBuffer(UwacWindow* window)
|
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);
|
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;
|
UwacFrameDoneEvent* event;
|
||||||
|
|
||||||
wl_callback_destroy(callback);
|
wl_callback_destroy(callback);
|
||||||
window->pendingBuffer = NULL;
|
window->pendingBufferIdx = -1;
|
||||||
event = (UwacFrameDoneEvent*)UwacDisplayNewEvent(window->display, UWAC_EVENT_FRAME_DONE);
|
event = (UwacFrameDoneEvent*)UwacDisplayNewEvent(window->display, UWAC_EVENT_FRAME_DONE);
|
||||||
|
|
||||||
if (event)
|
if (event)
|
||||||
@ -677,13 +695,20 @@ UwacReturnCode UwacWindowAddDamage(UwacWindow* window, uint32_t x, uint32_t y, u
|
|||||||
uint32_t height)
|
uint32_t height)
|
||||||
{
|
{
|
||||||
RECTANGLE_16 box;
|
RECTANGLE_16 box;
|
||||||
|
UwacBuffer* buf;
|
||||||
|
|
||||||
box.left = x;
|
box.left = x;
|
||||||
box.top = y;
|
box.top = y;
|
||||||
box.right = x + width;
|
box.right = x + width;
|
||||||
box.bottom = y + height;
|
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))
|
if (!region16_union_rect(&buf->damage, &buf->damage, &box))
|
||||||
return UWAC_ERROR_INTERNAL;
|
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,
|
UwacReturnCode UwacWindowGetDrawingBufferGeometry(UwacWindow* window, UwacSize* geometry,
|
||||||
size_t* stride)
|
size_t* stride)
|
||||||
{
|
{
|
||||||
if (!window || !window->drawingBuffer)
|
if (!window || (window->drawingBufferIdx < 0))
|
||||||
return UWAC_ERROR_INTERNAL;
|
return UWAC_ERROR_INTERNAL;
|
||||||
|
|
||||||
if (geometry)
|
if (geometry)
|
||||||
@ -712,22 +737,29 @@ UwacReturnCode UwacWindowGetDrawingBufferGeometry(UwacWindow* window, UwacSize*
|
|||||||
|
|
||||||
UwacReturnCode UwacWindowSubmitBuffer(UwacWindow* window, bool copyContentForNextFrame)
|
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;
|
return UWAC_SUCCESS;
|
||||||
|
|
||||||
window->pendingBuffer = drawingBuffer;
|
window->pendingBufferIdx = window->drawingBufferIdx;
|
||||||
window->drawingBuffer = UwacWindowFindFreeBuffer(window);
|
nextDrawingBuffer = UwacWindowFindFreeBuffer(window, &window->drawingBufferIdx);
|
||||||
|
pendingBuffer = &window->buffers[window->pendingBufferIdx];
|
||||||
|
|
||||||
if (!window->drawingBuffer)
|
if ((!nextDrawingBuffer) || (window->drawingBufferIdx < 0))
|
||||||
return UWAC_ERROR_NOMEMORY;
|
return UWAC_ERROR_NOMEMORY;
|
||||||
|
|
||||||
if (copyContentForNextFrame)
|
if (copyContentForNextFrame)
|
||||||
memcpy(window->drawingBuffer->data, window->pendingBuffer->data,
|
memcpy(nextDrawingBuffer->data, pendingBuffer->data, window->stride * window->height);
|
||||||
window->stride * window->height);
|
|
||||||
|
|
||||||
UwacSubmitBufferPtr(window, drawingBuffer);
|
UwacSubmitBufferPtr(window, pendingBuffer);
|
||||||
return UWAC_SUCCESS;
|
return UWAC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user