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. */
|
||||
struct wl_resource *resource;
|
||||
|
||||
/* List of "destroy listeners" connected to this buffer. */
|
||||
XLList *destroy_listeners;
|
||||
|
||||
/* The width and height of this buffer. */
|
||||
unsigned int width, height;
|
||||
|
||||
/* The number of references to this buffer. */
|
||||
int refcount;
|
||||
|
||||
/* Whether or not this buffer is actually a single-pixel buffer. */
|
||||
Bool is_fallback;
|
||||
};
|
||||
|
||||
struct _FormatModifierPair
|
||||
|
@ -123,6 +123,8 @@ static DrmFormat *supported_formats;
|
|||
/* Number of formats. */
|
||||
static int n_drm_formats;
|
||||
|
||||
|
||||
|
||||
static void
|
||||
CloseFdsEarly (BufferParams *params)
|
||||
{
|
||||
|
@ -268,8 +270,13 @@ DestroyBacking (Buffer *buffer)
|
|||
if (--buffer->refcount)
|
||||
return;
|
||||
|
||||
/* Free the renderer-specific dmabuf buffer. */
|
||||
RenderFreeDmabufBuffer (buffer->render_buffer);
|
||||
if (!buffer->is_fallback)
|
||||
/* 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);
|
||||
XLFree (buffer);
|
||||
|
@ -383,7 +390,6 @@ CreateBufferFor (BufferParams *params, RenderBuffer render_buffer,
|
|||
buffer->render_buffer = render_buffer;
|
||||
buffer->width = params->width;
|
||||
buffer->height = params->height;
|
||||
buffer->destroy_listeners = NULL;
|
||||
|
||||
/* Initialize function pointers. */
|
||||
buffer->buffer.funcs.retain = RetainBufferFunc;
|
||||
|
@ -629,6 +635,67 @@ Create (struct wl_client *client, struct wl_resource *resource, int32_t width,
|
|||
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
|
||||
CreateImmed (struct wl_client *client, struct wl_resource *resource, uint32_t id,
|
||||
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"
|
||||
" resource");
|
||||
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;
|
||||
}
|
||||
|
@ -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. */
|
||||
zwp_linux_buffer_params_v1_send_failed (resource);
|
||||
CreatePlaceholderBuffer (client, id, width, height);
|
||||
}
|
||||
else
|
||||
/* 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
|
||||
knowledge. Simply send an empty configure event to the
|
||||
client. */
|
||||
if (!toplevel->configuration_timer)
|
||||
client.
|
||||
|
||||
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);
|
||||
|
||||
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
|
||||
knowledge. Simply send an empty configure event to the
|
||||
client. */
|
||||
if (!toplevel->configuration_timer)
|
||||
if (!toplevel->configuration_timer
|
||||
&& !(toplevel->state & StateWaitingForInitialConfigure))
|
||||
SendConfigure (toplevel, 0, 0);
|
||||
|
||||
return;
|
||||
|
|
Loading…
Add table
Reference in a new issue