forked from 12to11/12to11
Fix compatibility with Chromium
* dmabuf.c (struct _Buffer): New field `is_fallback'. (DestroyBacking): Destroy fallback buffers appropriately. (CreatePlaceholderBuffer): New function. (CreateImmed): Create palceholder buffers upon a `failed' event being sent. * xdg_toplevel.c (UnsetMaximized, UnsetFullscreen): Add workarounds for Chromium bugs.
This commit is contained in:
parent
042e10486a
commit
94333293c8
2 changed files with 89 additions and 10 deletions
85
dmabuf.c
85
dmabuf.c
|
@ -83,14 +83,14 @@ struct _Buffer
|
||||||
/* The wl_resource corresponding to this buffer. */
|
/* The wl_resource corresponding to this buffer. */
|
||||||
struct wl_resource *resource;
|
struct wl_resource *resource;
|
||||||
|
|
||||||
/* List of "destroy listeners" connected to this buffer. */
|
|
||||||
XLList *destroy_listeners;
|
|
||||||
|
|
||||||
/* The width and height of this buffer. */
|
/* The width and height of this buffer. */
|
||||||
unsigned int width, height;
|
unsigned int width, height;
|
||||||
|
|
||||||
/* The number of references to this buffer. */
|
/* The number of references to this buffer. */
|
||||||
int refcount;
|
int refcount;
|
||||||
|
|
||||||
|
/* Whether or not this buffer is actually a single-pixel buffer. */
|
||||||
|
Bool is_fallback;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _FormatModifierPair
|
struct _FormatModifierPair
|
||||||
|
@ -123,6 +123,8 @@ static DrmFormat *supported_formats;
|
||||||
/* Number of formats. */
|
/* Number of formats. */
|
||||||
static int n_drm_formats;
|
static int n_drm_formats;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
CloseFdsEarly (BufferParams *params)
|
CloseFdsEarly (BufferParams *params)
|
||||||
{
|
{
|
||||||
|
@ -268,8 +270,13 @@ DestroyBacking (Buffer *buffer)
|
||||||
if (--buffer->refcount)
|
if (--buffer->refcount)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Free the renderer-specific dmabuf buffer. */
|
if (!buffer->is_fallback)
|
||||||
RenderFreeDmabufBuffer (buffer->render_buffer);
|
/* Free the renderer-specific dmabuf buffer. */
|
||||||
|
RenderFreeDmabufBuffer (buffer->render_buffer);
|
||||||
|
else
|
||||||
|
/* This is actually a fallback single-pixel buffer. Destroy it
|
||||||
|
instead. */
|
||||||
|
RenderFreeSinglePixelBuffer (buffer->render_buffer);
|
||||||
|
|
||||||
ExtBufferDestroy (&buffer->buffer);
|
ExtBufferDestroy (&buffer->buffer);
|
||||||
XLFree (buffer);
|
XLFree (buffer);
|
||||||
|
@ -383,7 +390,6 @@ CreateBufferFor (BufferParams *params, RenderBuffer render_buffer,
|
||||||
buffer->render_buffer = render_buffer;
|
buffer->render_buffer = render_buffer;
|
||||||
buffer->width = params->width;
|
buffer->width = params->width;
|
||||||
buffer->height = params->height;
|
buffer->height = params->height;
|
||||||
buffer->destroy_listeners = NULL;
|
|
||||||
|
|
||||||
/* Initialize function pointers. */
|
/* Initialize function pointers. */
|
||||||
buffer->buffer.funcs.retain = RetainBufferFunc;
|
buffer->buffer.funcs.retain = RetainBufferFunc;
|
||||||
|
@ -629,6 +635,67 @@ Create (struct wl_client *client, struct wl_resource *resource, int32_t width,
|
||||||
CloseFdsEarly (params);
|
CloseFdsEarly (params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
CreatePlaceholderBuffer (struct wl_client *client, uint32_t id,
|
||||||
|
int width, int height)
|
||||||
|
{
|
||||||
|
Buffer *buffer;
|
||||||
|
Bool error;
|
||||||
|
|
||||||
|
/* Create a placeholder buffer for the given client and dimensions.
|
||||||
|
The buffer is a completely transparent single-pixel buffer.
|
||||||
|
|
||||||
|
Such a placeholder buffer is required when
|
||||||
|
zwp_linux_buffer_params_v1.failed is posted in response to a
|
||||||
|
failed create_immed request. */
|
||||||
|
|
||||||
|
buffer = XLCalloc (1, sizeof *buffer);
|
||||||
|
buffer->resource = wl_resource_create (client, &wl_buffer_interface,
|
||||||
|
1, id);
|
||||||
|
buffer->is_fallback = True;
|
||||||
|
|
||||||
|
if (!buffer->resource)
|
||||||
|
{
|
||||||
|
wl_client_post_no_memory (client);
|
||||||
|
XLFree (buffer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A single pixel buffer is used because it is safe to read outside
|
||||||
|
them. */
|
||||||
|
error = False;
|
||||||
|
buffer->render_buffer = RenderBufferFromSinglePixel (0, 0, 0, 0,
|
||||||
|
&error);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
/* If an error occured, then we are probably out of memory. */
|
||||||
|
wl_resource_destroy (buffer->resource);
|
||||||
|
XLFree (buffer);
|
||||||
|
wl_client_post_no_memory (client);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add a reference. */
|
||||||
|
buffer->refcount = 1;
|
||||||
|
|
||||||
|
/* Set the width and height. */
|
||||||
|
buffer->width = width;
|
||||||
|
buffer->height = height;
|
||||||
|
|
||||||
|
/* Initialize virtual functions. */
|
||||||
|
buffer->buffer.funcs.retain = RetainBufferFunc;
|
||||||
|
buffer->buffer.funcs.dereference = DereferenceBufferFunc;
|
||||||
|
buffer->buffer.funcs.get_buffer = GetBufferFunc;
|
||||||
|
buffer->buffer.funcs.width = WidthFunc;
|
||||||
|
buffer->buffer.funcs.height = HeightFunc;
|
||||||
|
buffer->buffer.funcs.release = ReleaseBufferFunc;
|
||||||
|
|
||||||
|
wl_resource_set_implementation (buffer->resource,
|
||||||
|
&zwp_linux_dmabuf_v1_buffer_impl,
|
||||||
|
buffer, HandleBufferResourceDestroy);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
CreateImmed (struct wl_client *client, struct wl_resource *resource, uint32_t id,
|
CreateImmed (struct wl_client *client, struct wl_resource *resource, uint32_t id,
|
||||||
int32_t width, int32_t height, uint32_t format, uint32_t flags)
|
int32_t width, int32_t height, uint32_t format, uint32_t flags)
|
||||||
|
@ -716,7 +783,10 @@ CreateImmed (struct wl_client *client, struct wl_resource *resource, uint32_t id
|
||||||
"invalid format/modifiers specified for version 4"
|
"invalid format/modifiers specified for version 4"
|
||||||
" resource");
|
" resource");
|
||||||
else
|
else
|
||||||
zwp_linux_buffer_params_v1_send_failed (resource);
|
{
|
||||||
|
zwp_linux_buffer_params_v1_send_failed (resource);
|
||||||
|
CreatePlaceholderBuffer (client, id, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
goto inert_error;
|
goto inert_error;
|
||||||
}
|
}
|
||||||
|
@ -769,6 +839,7 @@ CreateImmed (struct wl_client *client, struct wl_resource *resource, uint32_t id
|
||||||
{
|
{
|
||||||
/* The fds should have been closed by the renderer. */
|
/* The fds should have been closed by the renderer. */
|
||||||
zwp_linux_buffer_params_v1_send_failed (resource);
|
zwp_linux_buffer_params_v1_send_failed (resource);
|
||||||
|
CreatePlaceholderBuffer (client, id, width, height);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* Otherwise, buffer creation was successful. Create the buffer
|
/* Otherwise, buffer creation was successful. Create the buffer
|
||||||
|
|
|
@ -2224,8 +2224,15 @@ UnsetMaximized (struct wl_client *client, struct wl_resource *resource)
|
||||||
{
|
{
|
||||||
/* The toplevel is already unmaximized to the best of our
|
/* The toplevel is already unmaximized to the best of our
|
||||||
knowledge. Simply send an empty configure event to the
|
knowledge. Simply send an empty configure event to the
|
||||||
client. */
|
client.
|
||||||
if (!toplevel->configuration_timer)
|
|
||||||
|
However, avoid all of this if the surface's initial commit
|
||||||
|
has not yet been sent. This is because Chromium gets
|
||||||
|
confused if any configure event arrives before the initial
|
||||||
|
commit, and fails to ack the initial commit before it commits
|
||||||
|
the xdg surface itself. */
|
||||||
|
if (!toplevel->configuration_timer
|
||||||
|
&& !(toplevel->state & StateWaitingForInitialConfigure))
|
||||||
SendConfigure (toplevel, 0, 0);
|
SendConfigure (toplevel, 0, 0);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -2283,7 +2290,8 @@ UnsetFullscreen (struct wl_client *client, struct wl_resource *resource)
|
||||||
/* The toplevel is already not fullscreen to the best of our
|
/* The toplevel is already not fullscreen to the best of our
|
||||||
knowledge. Simply send an empty configure event to the
|
knowledge. Simply send an empty configure event to the
|
||||||
client. */
|
client. */
|
||||||
if (!toplevel->configuration_timer)
|
if (!toplevel->configuration_timer
|
||||||
|
&& !(toplevel->state & StateWaitingForInitialConfigure))
|
||||||
SendConfigure (toplevel, 0, 0);
|
SendConfigure (toplevel, 0, 0);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Add table
Reference in a new issue