mirror of
https://github.com/brl/mutter.git
synced 2025-02-23 08:24:09 +00:00
wayland: Add support for EGL_WAYLAND_Y_INVERTED_WL
Add support for inverted Y Wayland buffers. OpenGL textures are by default inverted, so adding support for EGL_WAYLAND_Y_INVERTED_WL effectively means adding support for non-inverted, which makes the MetaShapedTexture apply a transformation when drawing only when querying EGL_WAYLAND_Y_INVERTED_WL resulted in the response "EGL_FALSE". https://bugzilla.gnome.org/show_bug.cgi?id=773629
This commit is contained in:
parent
23455985cd
commit
41c96921d6
@ -32,6 +32,8 @@
|
||||
ClutterActor *meta_shaped_texture_new (void);
|
||||
void meta_shaped_texture_set_texture (MetaShapedTexture *stex,
|
||||
CoglTexture *texture);
|
||||
void meta_shaped_texture_set_is_y_inverted (MetaShapedTexture *stex,
|
||||
gboolean is_y_inverted);
|
||||
void meta_shaped_texture_set_fallback_size (MetaShapedTexture *stex,
|
||||
guint fallback_width,
|
||||
guint fallback_height);
|
||||
|
@ -78,6 +78,12 @@ struct _MetaShapedTexturePrivate
|
||||
CoglTexture *texture;
|
||||
CoglTexture *mask_texture;
|
||||
|
||||
CoglPipeline *base_pipeline;
|
||||
CoglPipeline *masked_pipeline;
|
||||
CoglPipeline *unblended_pipeline;
|
||||
|
||||
gboolean is_y_inverted;
|
||||
|
||||
/* The region containing only fully opaque pixels */
|
||||
cairo_region_t *opaque_region;
|
||||
|
||||
@ -167,6 +173,16 @@ set_clip_region (MetaShapedTexture *self,
|
||||
priv->clip_region = cairo_region_copy (clip_region);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_shaped_texture_reset_pipelines (MetaShapedTexture *stex)
|
||||
{
|
||||
MetaShapedTexturePrivate *priv = stex->priv;
|
||||
|
||||
g_clear_pointer (&priv->base_pipeline, cogl_object_unref);
|
||||
g_clear_pointer (&priv->masked_pipeline, cogl_object_unref);
|
||||
g_clear_pointer (&priv->unblended_pipeline, cogl_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_shaped_texture_dispose (GObject *object)
|
||||
{
|
||||
@ -184,61 +200,93 @@ meta_shaped_texture_dispose (GObject *object)
|
||||
set_unobscured_region (self, NULL);
|
||||
set_clip_region (self, NULL);
|
||||
|
||||
meta_shaped_texture_reset_pipelines (self);
|
||||
|
||||
G_OBJECT_CLASS (meta_shaped_texture_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static CoglPipeline *
|
||||
get_base_pipeline (CoglContext *ctx)
|
||||
get_base_pipeline (MetaShapedTexture *stex,
|
||||
CoglContext *ctx)
|
||||
{
|
||||
static CoglPipeline *template = NULL;
|
||||
if (G_UNLIKELY (template == NULL))
|
||||
MetaShapedTexturePrivate *priv = stex->priv;
|
||||
CoglPipeline *pipeline;
|
||||
|
||||
if (priv->base_pipeline)
|
||||
return priv->base_pipeline;
|
||||
|
||||
pipeline = cogl_pipeline_new (ctx);
|
||||
cogl_pipeline_set_layer_wrap_mode_s (pipeline, 0,
|
||||
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
|
||||
cogl_pipeline_set_layer_wrap_mode_t (pipeline, 0,
|
||||
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
|
||||
cogl_pipeline_set_layer_wrap_mode_s (pipeline, 1,
|
||||
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
|
||||
cogl_pipeline_set_layer_wrap_mode_t (pipeline, 1,
|
||||
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
|
||||
if (!priv->is_y_inverted)
|
||||
{
|
||||
template = cogl_pipeline_new (ctx);
|
||||
cogl_pipeline_set_layer_wrap_mode_s (template, 0, COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
|
||||
cogl_pipeline_set_layer_wrap_mode_t (template, 0, COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
|
||||
cogl_pipeline_set_layer_wrap_mode_s (template, 1, COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
|
||||
cogl_pipeline_set_layer_wrap_mode_t (template, 1, COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
|
||||
CoglMatrix matrix;
|
||||
|
||||
cogl_matrix_init_identity (&matrix);
|
||||
cogl_matrix_scale (&matrix, 1, -1, 1);
|
||||
cogl_matrix_translate (&matrix, 0, -1, 0);
|
||||
cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix);
|
||||
}
|
||||
return template;
|
||||
|
||||
priv->base_pipeline = pipeline;
|
||||
|
||||
return priv->base_pipeline;
|
||||
}
|
||||
|
||||
static CoglPipeline *
|
||||
get_unmasked_pipeline (CoglContext *ctx)
|
||||
get_unmasked_pipeline (MetaShapedTexture *stex,
|
||||
CoglContext *ctx)
|
||||
{
|
||||
return get_base_pipeline (ctx);
|
||||
return get_base_pipeline (stex, ctx);
|
||||
}
|
||||
|
||||
static CoglPipeline *
|
||||
get_masked_pipeline (CoglContext *ctx)
|
||||
get_masked_pipeline (MetaShapedTexture *stex,
|
||||
CoglContext *ctx)
|
||||
{
|
||||
static CoglPipeline *template = NULL;
|
||||
if (G_UNLIKELY (template == NULL))
|
||||
{
|
||||
template = cogl_pipeline_copy (get_base_pipeline (ctx));
|
||||
cogl_pipeline_set_layer_combine (template, 1,
|
||||
MetaShapedTexturePrivate *priv = stex->priv;
|
||||
CoglPipeline *pipeline;
|
||||
|
||||
if (priv->masked_pipeline)
|
||||
return priv->masked_pipeline;
|
||||
|
||||
pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
|
||||
cogl_pipeline_set_layer_combine (pipeline, 1,
|
||||
"RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
|
||||
NULL);
|
||||
}
|
||||
|
||||
return template;
|
||||
priv->masked_pipeline = pipeline;
|
||||
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
static CoglPipeline *
|
||||
get_unblended_pipeline (CoglContext *ctx)
|
||||
{
|
||||
static CoglPipeline *template = NULL;
|
||||
if (G_UNLIKELY (template == NULL))
|
||||
get_unblended_pipeline (MetaShapedTexture *stex,
|
||||
CoglContext *ctx)
|
||||
{
|
||||
MetaShapedTexturePrivate *priv = stex->priv;
|
||||
CoglPipeline *pipeline;
|
||||
CoglColor color;
|
||||
template = cogl_pipeline_copy (get_base_pipeline (ctx));
|
||||
|
||||
if (priv->unblended_pipeline)
|
||||
return priv->unblended_pipeline;
|
||||
|
||||
pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
|
||||
cogl_color_init_from_4ub (&color, 255, 255, 255, 255);
|
||||
cogl_pipeline_set_blend (template,
|
||||
cogl_pipeline_set_blend (pipeline,
|
||||
"RGBA = ADD (SRC_COLOR, 0)",
|
||||
NULL);
|
||||
cogl_pipeline_set_color (template, &color);
|
||||
}
|
||||
cogl_pipeline_set_color (pipeline, &color);
|
||||
|
||||
return template;
|
||||
priv->unblended_pipeline = pipeline;
|
||||
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -439,7 +487,7 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
||||
|
||||
if (!cairo_region_is_empty (region))
|
||||
{
|
||||
opaque_pipeline = get_unblended_pipeline (ctx);
|
||||
opaque_pipeline = get_unblended_pipeline (stex, ctx);
|
||||
cogl_pipeline_set_layer_texture (opaque_pipeline, 0, paint_tex);
|
||||
cogl_pipeline_set_layer_filters (opaque_pipeline, 0, filter, filter);
|
||||
|
||||
@ -471,11 +519,11 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
||||
|
||||
if (priv->mask_texture == NULL)
|
||||
{
|
||||
blended_pipeline = get_unmasked_pipeline (ctx);
|
||||
blended_pipeline = get_unmasked_pipeline (stex, ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
blended_pipeline = get_masked_pipeline (ctx);
|
||||
blended_pipeline = get_masked_pipeline (stex, ctx);
|
||||
cogl_pipeline_set_layer_texture (blended_pipeline, 1, priv->mask_texture);
|
||||
cogl_pipeline_set_layer_filters (blended_pipeline, 1, filter, filter);
|
||||
}
|
||||
@ -747,6 +795,23 @@ meta_shaped_texture_set_texture (MetaShapedTexture *stex,
|
||||
set_cogl_texture (stex, texture);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_shaped_texture_set_is_y_inverted: (skip)
|
||||
*/
|
||||
void
|
||||
meta_shaped_texture_set_is_y_inverted (MetaShapedTexture *stex,
|
||||
gboolean is_y_inverted)
|
||||
{
|
||||
MetaShapedTexturePrivate *priv = stex->priv;
|
||||
|
||||
if (priv->is_y_inverted == is_y_inverted)
|
||||
return;
|
||||
|
||||
meta_shaped_texture_reset_pipelines (stex);
|
||||
|
||||
priv->is_y_inverted = is_y_inverted;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_shaped_texture_get_texture:
|
||||
* @stex: The #MetaShapedTexture
|
||||
|
@ -191,6 +191,7 @@ shm_buffer_attach (MetaWaylandBuffer *buffer,
|
||||
wl_shm_buffer_end_access (shm_buffer);
|
||||
|
||||
buffer->texture = texture;
|
||||
buffer->is_y_inverted = TRUE;
|
||||
|
||||
if (!buffer->texture)
|
||||
return FALSE;
|
||||
@ -208,7 +209,7 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
|
||||
CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
|
||||
EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context);
|
||||
EGLContext egl_context = cogl_egl_context_get_egl_context (cogl_context);
|
||||
int format, width, height;
|
||||
int format, width, height, y_inverted;
|
||||
CoglPixelFormat cogl_format;
|
||||
EGLImageKHR egl_image;
|
||||
CoglTexture2D *texture;
|
||||
@ -231,6 +232,11 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
if (!meta_egl_query_wayland_buffer (egl, egl_display, buffer->resource,
|
||||
EGL_WAYLAND_Y_INVERTED_WL, &y_inverted,
|
||||
NULL))
|
||||
y_inverted = EGL_TRUE;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case EGL_TEXTURE_RGB:
|
||||
@ -265,6 +271,7 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
|
||||
return FALSE;
|
||||
|
||||
buffer->texture = COGL_TEXTURE (texture);
|
||||
buffer->is_y_inverted = !!y_inverted;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -301,6 +308,12 @@ meta_wayland_buffer_get_texture (MetaWaylandBuffer *buffer)
|
||||
return buffer->texture;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_wayland_buffer_is_y_inverted (MetaWaylandBuffer *buffer)
|
||||
{
|
||||
return buffer->is_y_inverted;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
process_shm_buffer_damage (MetaWaylandBuffer *buffer,
|
||||
cairo_region_t *region,
|
||||
|
@ -39,6 +39,7 @@ struct _MetaWaylandBuffer
|
||||
struct wl_listener destroy_listener;
|
||||
|
||||
CoglTexture *texture;
|
||||
gboolean is_y_inverted;
|
||||
};
|
||||
|
||||
#define META_TYPE_WAYLAND_BUFFER (meta_wayland_buffer_get_type ())
|
||||
@ -49,6 +50,7 @@ MetaWaylandBuffer * meta_wayland_buffer_from_resource (struct wl_resou
|
||||
gboolean meta_wayland_buffer_attach (MetaWaylandBuffer *buffer,
|
||||
GError **error);
|
||||
CoglTexture * meta_wayland_buffer_get_texture (MetaWaylandBuffer *buffer);
|
||||
gboolean meta_wayland_buffer_is_y_inverted (MetaWaylandBuffer *buffer);
|
||||
void meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer,
|
||||
cairo_region_t *region);
|
||||
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include "meta-window-wayland.h"
|
||||
|
||||
#include "compositor/region-utils.h"
|
||||
#include "compositor/meta-shaped-texture-private.h"
|
||||
|
||||
#include "meta-surface-actor.h"
|
||||
#include "meta-surface-actor-wayland.h"
|
||||
@ -701,9 +702,6 @@ static void
|
||||
apply_pending_state (MetaWaylandSurface *surface,
|
||||
MetaWaylandPendingState *pending)
|
||||
{
|
||||
MetaSurfaceActorWayland *surface_actor_wayland =
|
||||
META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
|
||||
|
||||
if (surface->role)
|
||||
{
|
||||
meta_wayland_surface_role_pre_commit (surface->role, pending);
|
||||
@ -755,11 +753,16 @@ apply_pending_state (MetaWaylandSurface *surface,
|
||||
|
||||
if (switched_buffer)
|
||||
{
|
||||
MetaShapedTexture *stex;
|
||||
CoglTexture *texture;
|
||||
gboolean is_y_inverted;
|
||||
|
||||
stex = meta_surface_actor_get_texture (surface->surface_actor);
|
||||
texture = meta_wayland_buffer_get_texture (pending->buffer);
|
||||
meta_surface_actor_wayland_set_texture (surface_actor_wayland,
|
||||
texture);
|
||||
is_y_inverted = meta_wayland_buffer_is_y_inverted (pending->buffer);
|
||||
|
||||
meta_shaped_texture_set_texture (stex, texture);
|
||||
meta_shaped_texture_set_is_y_inverted (stex, is_y_inverted);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user