shaped-texture: Start using MetaMultiTexture

To be able to later support more complex YUV formats, we need to make
sure that MetaShapedTexture (the one who will actually render the
texture) can use the MetaMultiTexture class.

Co-Authored-By: Robert Mader <robert.mader@collabora.com>
Co-Authored-By: Daniel van Vugt <daniel.van.vugt@canonical.com>
Co-Authored-By: Sebastian Wick <sebastian.wick@redhat.com>
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2191>
This commit is contained in:
Niels De Graef 2023-05-29 14:41:00 +02:00 committed by Marge Bot
parent 5181a826d1
commit 3dd9f15eba
16 changed files with 289 additions and 160 deletions

View File

@ -32,7 +32,7 @@
MetaShapedTexture * meta_shaped_texture_new (void);
void meta_shaped_texture_set_texture (MetaShapedTexture *stex,
CoglTexture *texture);
MetaMultiTexture *multi_texture);
void meta_shaped_texture_set_is_y_inverted (MetaShapedTexture *stex,
gboolean is_y_inverted);
void meta_shaped_texture_set_snippet (MetaShapedTexture *stex,

View File

@ -35,6 +35,7 @@
#include "config.h"
#include "backends/meta-monitor-transform.h"
#include "compositor/meta-multi-texture-format-private.h"
#include "compositor/meta-shaped-texture-private.h"
#include "core/boxes-private.h"
@ -69,11 +70,12 @@ struct _MetaShapedTexture
{
GObject parent;
CoglTexture *texture;
MetaMultiTexture *texture;
CoglTexture *mask_texture;
CoglSnippet *snippet;
CoglPipeline *base_pipeline;
CoglPipeline *combined_pipeline;
CoglPipeline *unmasked_pipeline;
CoglPipeline *unmasked_tower_pipeline;
CoglPipeline *masked_pipeline;
@ -225,6 +227,7 @@ static void
meta_shaped_texture_reset_pipelines (MetaShapedTexture *stex)
{
g_clear_pointer (&stex->base_pipeline, cogl_object_unref);
g_clear_pointer (&stex->combined_pipeline, cogl_object_unref);
g_clear_pointer (&stex->unmasked_pipeline, cogl_object_unref);
g_clear_pointer (&stex->unmasked_tower_pipeline, cogl_object_unref);
g_clear_pointer (&stex->masked_pipeline, cogl_object_unref);
@ -259,19 +262,23 @@ get_base_pipeline (MetaShapedTexture *stex,
{
CoglPipeline *pipeline;
graphene_matrix_t matrix;
int i, n_planes;
if (stex->base_pipeline)
return stex->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);
/* We'll add as many layers as there are planes in the multi texture,
* plus an extra one for the mask */
n_planes = meta_multi_texture_get_n_planes (stex->texture);
for (i = 0; i < (n_planes + 1); i++)
{
cogl_pipeline_set_layer_wrap_mode_s (pipeline, i,
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
cogl_pipeline_set_layer_wrap_mode_t (pipeline, i,
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
}
graphene_matrix_init_identity (&matrix);
@ -320,17 +327,55 @@ get_base_pipeline (MetaShapedTexture *stex,
graphene_matrix_scale (&matrix, 1, -1, 1);
}
cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix);
for (i = 0; i < n_planes; i++)
cogl_pipeline_set_layer_matrix (pipeline, i, &matrix);
stex->base_pipeline = pipeline;
return stex->base_pipeline;
return pipeline;
}
static CoglPipeline *
get_combined_pipeline (MetaShapedTexture *stex,
CoglContext *ctx)
{
MetaMultiTextureFormat format;
CoglPipeline *pipeline;
CoglSnippet *fragment_globals_snippet;
CoglSnippet *fragment_snippet;
int i, n_planes;
if (stex->combined_pipeline)
return stex->combined_pipeline;
pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
format = meta_multi_texture_get_format (stex->texture);
n_planes = meta_multi_texture_get_n_planes (stex->texture);
for (i = 0; i < n_planes; i++)
{
cogl_pipeline_set_layer_combine (pipeline, i,
"RGBA = REPLACE(TEXTURE)", NULL);
}
meta_multi_texture_format_get_snippets (format,
&fragment_globals_snippet,
&fragment_snippet);
cogl_pipeline_add_snippet (pipeline, fragment_globals_snippet);
cogl_pipeline_add_snippet (pipeline, fragment_snippet);
cogl_clear_object (&fragment_globals_snippet);
cogl_clear_object (&fragment_snippet);
stex->combined_pipeline = pipeline;
return pipeline;
}
static CoglPipeline *
get_unmasked_pipeline (MetaShapedTexture *stex,
CoglContext *ctx,
CoglTexture *tex)
MetaMultiTexture *tex)
{
if (stex->texture == tex)
{
@ -339,7 +384,7 @@ get_unmasked_pipeline (MetaShapedTexture *stex,
if (stex->unmasked_pipeline)
return stex->unmasked_pipeline;
pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
pipeline = cogl_pipeline_copy (get_combined_pipeline (stex, ctx));
if (stex->snippet)
cogl_pipeline_add_layer_snippet (pipeline, 0, stex->snippet);
@ -362,8 +407,10 @@ get_unmasked_pipeline (MetaShapedTexture *stex,
static CoglPipeline *
get_masked_pipeline (MetaShapedTexture *stex,
CoglContext *ctx,
CoglTexture *tex)
MetaMultiTexture *tex)
{
g_assert (meta_multi_texture_get_n_planes (stex->texture) == 1);
if (stex->texture == tex)
{
CoglPipeline *pipeline;
@ -401,7 +448,7 @@ get_masked_pipeline (MetaShapedTexture *stex,
static CoglPipeline *
get_unblended_pipeline (MetaShapedTexture *stex,
CoglContext *ctx,
CoglTexture *tex)
MetaMultiTexture *tex)
{
if (stex->texture == tex)
{
@ -410,7 +457,7 @@ get_unblended_pipeline (MetaShapedTexture *stex,
if (stex->unblended_pipeline)
return stex->unblended_pipeline;
pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
pipeline = cogl_pipeline_copy (get_combined_pipeline (stex, ctx));
cogl_pipeline_set_layer_combine (pipeline, 0,
"RGBA = REPLACE (TEXTURE)",
NULL);
@ -527,18 +574,18 @@ paint_clipped_rectangle_node (MetaShapedTexture *stex,
}
static void
set_cogl_texture (MetaShapedTexture *stex,
CoglTexture *cogl_tex)
set_multi_texture (MetaShapedTexture *stex,
MetaMultiTexture *multi_tex)
{
int width, height;
cogl_clear_object (&stex->texture);
g_clear_object (&stex->texture);
if (cogl_tex != NULL)
if (multi_tex != NULL)
{
stex->texture = cogl_object_ref (cogl_tex);
width = cogl_texture_get_width (COGL_TEXTURE (cogl_tex));
height = cogl_texture_get_height (COGL_TEXTURE (cogl_tex));
stex->texture = g_object_ref (multi_tex);
width = meta_multi_texture_get_width (multi_tex);
height = meta_multi_texture_get_height (multi_tex);
}
else
{
@ -584,10 +631,11 @@ do_paint_content (MetaShapedTexture *stex,
CoglContext *ctx;
CoglPipelineFilter min_filter, mag_filter;
MetaTransforms transforms;
CoglTexture *paint_tex = stex->texture;
MetaMultiTexture *paint_tex = stex->texture;
CoglFramebuffer *framebuffer;
int sample_width, sample_height;
gboolean debug_paint_opaque_region;
int n_planes;
meta_shaped_texture_ensure_size_valid (stex);
@ -622,8 +670,8 @@ do_paint_content (MetaShapedTexture *stex,
}
else
{
sample_width = cogl_texture_get_width (stex->texture);
sample_height = cogl_texture_get_height (stex->texture);
sample_width = meta_multi_texture_get_width (stex->texture);
sample_height = meta_multi_texture_get_height (stex->texture);
}
if (meta_monitor_transform_is_rotated (stex->transform))
flip_ints (&sample_width, &sample_height);
@ -692,6 +740,8 @@ do_paint_content (MetaShapedTexture *stex,
}
}
n_planes = meta_multi_texture_get_n_planes (paint_tex);
/* First, paint the unblended parts, which are part of the opaque region. */
if (use_opaque_region)
{
@ -714,8 +764,15 @@ do_paint_content (MetaShapedTexture *stex,
CoglPipeline *opaque_pipeline;
opaque_pipeline = get_unblended_pipeline (stex, ctx, paint_tex);
cogl_pipeline_set_layer_texture (opaque_pipeline, 0, paint_tex);
cogl_pipeline_set_layer_filters (opaque_pipeline, 0, min_filter, mag_filter);
for (i = 0; i < n_planes; i++)
{
CoglTexture *plane = meta_multi_texture_get_plane (paint_tex, i);
cogl_pipeline_set_layer_texture (opaque_pipeline, i, plane);
cogl_pipeline_set_layer_filters (opaque_pipeline, i,
min_filter, mag_filter);
}
n_rects = cairo_region_num_rectangles (region);
for (i = 0; i < n_rects; i++)
@ -755,6 +812,7 @@ do_paint_content (MetaShapedTexture *stex,
{
CoglPipeline *blended_pipeline;
CoglColor color;
int i;
if (stex->mask_texture == NULL)
{
@ -763,12 +821,17 @@ do_paint_content (MetaShapedTexture *stex,
else
{
blended_pipeline = get_masked_pipeline (stex, ctx, paint_tex);
cogl_pipeline_set_layer_texture (blended_pipeline, 1, stex->mask_texture);
cogl_pipeline_set_layer_filters (blended_pipeline, 1, min_filter, mag_filter);
cogl_pipeline_set_layer_texture (blended_pipeline, n_planes, stex->mask_texture);
cogl_pipeline_set_layer_filters (blended_pipeline, n_planes, min_filter, mag_filter);
}
cogl_pipeline_set_layer_texture (blended_pipeline, 0, paint_tex);
cogl_pipeline_set_layer_filters (blended_pipeline, 0, min_filter, mag_filter);
for (i = 0; i < n_planes; i++)
{
CoglTexture *plane = meta_multi_texture_get_plane (paint_tex, i);
cogl_pipeline_set_layer_texture (blended_pipeline, i, plane);
cogl_pipeline_set_layer_filters (blended_pipeline, i, min_filter, mag_filter);
}
cogl_color_init_from_4ub (&color, opacity, opacity, opacity, opacity);
cogl_pipeline_set_color (blended_pipeline, &color);
@ -1055,18 +1118,18 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
/**
* meta_shaped_texture_set_texture:
* @stex: The #MetaShapedTexture
* @pixmap: The #CoglTexture to display
* @pixmap: The #MetaMultiTexture to display
*/
void
meta_shaped_texture_set_texture (MetaShapedTexture *stex,
CoglTexture *texture)
MetaMultiTexture *texture)
{
g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
if (stex->texture == texture)
return;
set_cogl_texture (stex, texture);
set_multi_texture (stex, texture);
}
/**
@ -1107,11 +1170,11 @@ meta_shaped_texture_set_snippet (MetaShapedTexture *stex,
*
* Returns: (transfer none): the unshaped texture
*/
CoglTexture *
MetaMultiTexture *
meta_shaped_texture_get_texture (MetaShapedTexture *stex)
{
g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), NULL);
return COGL_TEXTURE (stex->texture);
return stex->texture;
}
/**
@ -1143,13 +1206,18 @@ meta_shaped_texture_get_opaque_region (MetaShapedTexture *stex)
gboolean
meta_shaped_texture_has_alpha (MetaShapedTexture *stex)
{
CoglTexture *texture;
MetaMultiTexture *multi_texture;
CoglTexture *cogl_texture;
texture = stex->texture;
if (!texture)
multi_texture = stex->texture;
if (!multi_texture)
return TRUE;
switch (cogl_texture_get_components (texture))
if (!meta_multi_texture_is_simple (multi_texture))
return FALSE;
cogl_texture = meta_multi_texture_get_plane (multi_texture, 0);
switch (cogl_texture_get_components (cogl_texture))
{
case COGL_TEXTURE_COMPONENTS_A:
case COGL_TEXTURE_COMPONENTS_RGBA:
@ -1167,12 +1235,12 @@ meta_shaped_texture_has_alpha (MetaShapedTexture *stex)
gboolean
meta_shaped_texture_is_opaque (MetaShapedTexture *stex)
{
CoglTexture *texture;
MetaMultiTexture *multi_texture;
cairo_rectangle_int_t opaque_rect;
texture = stex->texture;
if (!texture)
return FALSE;
multi_texture = stex->texture;
if (!multi_texture)
return TRUE;
if (!meta_shaped_texture_has_alpha (stex))
return TRUE;
@ -1301,10 +1369,16 @@ meta_shaped_texture_reset_viewport_dst_size (MetaShapedTexture *stex)
gboolean
meta_shaped_texture_should_get_via_offscreen (MetaShapedTexture *stex)
{
CoglTexture *cogl_texture;
if (stex->mask_texture != NULL)
return TRUE;
if (!cogl_texture_is_get_data_supported (stex->texture))
if (meta_multi_texture_get_n_planes (stex->texture) > 1)
return FALSE;
cogl_texture = meta_multi_texture_get_plane (stex->texture, 0);
if (!cogl_texture_is_get_data_supported (cogl_texture))
return TRUE;
if (stex->has_viewport_src_rect || stex->has_viewport_dst_size)
@ -1353,9 +1427,7 @@ meta_shaped_texture_get_image (MetaShapedTexture *stex,
g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), NULL);
texture = COGL_TEXTURE (stex->texture);
if (texture == NULL)
if (stex->texture == NULL)
return NULL;
if (meta_shaped_texture_should_get_via_offscreen (stex))
@ -1388,6 +1460,9 @@ meta_shaped_texture_get_image (MetaShapedTexture *stex,
};
}
/* We know that we only have 1 plane at this point */
texture = meta_multi_texture_get_plane (stex->texture, 0);
if (image_clip)
texture = COGL_TEXTURE (cogl_sub_texture_new (cogl_context,
texture,

View File

@ -46,7 +46,7 @@ struct _MetaSurfaceActorX11
MetaDisplay *display;
CoglTexture *texture;
MetaMultiTexture *texture;
Pixmap pixmap;
Damage damage;
@ -109,7 +109,7 @@ detach_pixmap (MetaSurfaceActorX11 *self)
self->pixmap = None;
meta_x11_error_trap_pop (display->x11_display);
g_clear_pointer (&self->texture, cogl_object_unref);
g_clear_object (&self->texture);
}
static void
@ -119,23 +119,23 @@ set_pixmap (MetaSurfaceActorX11 *self,
CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
GError *error = NULL;
CoglTexture *texture;
CoglTexture *cogl_texture;
g_assert (self->pixmap == None);
self->pixmap = pixmap;
texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, self->pixmap, FALSE, &error));
cogl_texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, self->pixmap, FALSE, &error));
if (error != NULL)
{
g_warning ("Failed to allocate stex texture: %s", error->message);
g_error_free (error);
}
else if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 (texture))))
else if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 (cogl_texture))))
g_warning ("NOTE: Not using GLX TFP!");
self->texture = texture;
meta_shaped_texture_set_texture (stex, texture);
self->texture = meta_multi_texture_new_simple (cogl_texture);
meta_shaped_texture_set_texture (stex, self->texture);
}
static void
@ -195,6 +195,7 @@ meta_surface_actor_x11_process_damage (MetaSurfaceActor *actor,
int height)
{
MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor);
CoglTexturePixmapX11 *pixmap;
self->received_damage = TRUE;
@ -218,8 +219,12 @@ meta_surface_actor_x11_process_damage (MetaSurfaceActor *actor,
if (!meta_surface_actor_x11_is_visible (self))
return;
cogl_texture_pixmap_x11_update_area (COGL_TEXTURE_PIXMAP_X11 (self->texture),
x, y, width, height);
/* We don't support multi-plane or YUV based formats in X */
if (!meta_multi_texture_is_simple (self->texture))
return;
pixmap = COGL_TEXTURE_PIXMAP_X11 (meta_multi_texture_get_plane (self->texture, 0));
cogl_texture_pixmap_x11_update_area (pixmap, x, y, width, height);
meta_surface_actor_update_area (actor, x, y, width, height);
}

View File

@ -25,14 +25,15 @@
#include "config.h"
#include "compositor/meta-texture-mipmap.h"
#include "compositor/meta-multi-texture-format-private.h"
#include <math.h>
#include <string.h>
struct _MetaTextureMipmap
{
CoglTexture *base_texture;
CoglTexture *mipmap_texture;
MetaMultiTexture *base_texture;
MetaMultiTexture *mipmap_texture;
CoglPipeline *pipeline;
CoglFramebuffer *fb;
gboolean invalid;
@ -68,8 +69,8 @@ meta_texture_mipmap_free (MetaTextureMipmap *mipmap)
g_return_if_fail (mipmap != NULL);
cogl_clear_object (&mipmap->pipeline);
cogl_clear_object (&mipmap->base_texture);
cogl_clear_object (&mipmap->mipmap_texture);
g_clear_object (&mipmap->base_texture);
g_clear_object (&mipmap->mipmap_texture);
g_clear_object (&mipmap->fb);
g_free (mipmap);
@ -87,20 +88,20 @@ meta_texture_mipmap_free (MetaTextureMipmap *mipmap)
*/
void
meta_texture_mipmap_set_base_texture (MetaTextureMipmap *mipmap,
CoglTexture *texture)
MetaMultiTexture *texture)
{
g_return_if_fail (mipmap != NULL);
if (texture == mipmap->base_texture)
return;
cogl_clear_object (&mipmap->base_texture);
g_clear_object (&mipmap->base_texture);
mipmap->base_texture = texture;
if (mipmap->base_texture != NULL)
{
cogl_object_ref (mipmap->base_texture);
g_object_ref (mipmap->base_texture);
mipmap->invalid = TRUE;
}
}
@ -117,7 +118,7 @@ static void
free_mipmaps (MetaTextureMipmap *mipmap)
{
g_clear_object (&mipmap->fb);
cogl_clear_object (&mipmap->mipmap_texture);
g_clear_object (&mipmap->mipmap_texture);
}
void
@ -150,8 +151,8 @@ ensure_mipmap_texture (MetaTextureMipmap *mipmap)
* then just use the original texture instead of mipmap texture, which is
* faster anyway.
*/
width = cogl_texture_get_width (mipmap->base_texture) / 2;
height = cogl_texture_get_height (mipmap->base_texture) / 2;
width = meta_multi_texture_get_width (mipmap->base_texture) / 2;
height = meta_multi_texture_get_height (mipmap->base_texture) / 2;
if (!width || !height)
{
@ -160,11 +161,12 @@ ensure_mipmap_texture (MetaTextureMipmap *mipmap)
}
if (!mipmap->mipmap_texture ||
cogl_texture_get_width (mipmap->mipmap_texture) != width ||
cogl_texture_get_height (mipmap->mipmap_texture) != height)
meta_multi_texture_get_width (mipmap->mipmap_texture) != width ||
meta_multi_texture_get_height (mipmap->mipmap_texture) != height)
{
CoglOffscreen *offscreen;
CoglTexture2D *tex2d;
CoglTexture *tex;
free_mipmaps (mipmap);
@ -172,9 +174,10 @@ ensure_mipmap_texture (MetaTextureMipmap *mipmap)
if (!tex2d)
return;
mipmap->mipmap_texture = COGL_TEXTURE (tex2d);
tex = COGL_TEXTURE (tex2d);
mipmap->mipmap_texture = meta_multi_texture_new_simple (tex);
offscreen = cogl_offscreen_new_with_texture (mipmap->mipmap_texture);
offscreen = cogl_offscreen_new_with_texture (tex);
if (!offscreen)
{
free_mipmaps (mipmap);
@ -197,16 +200,49 @@ ensure_mipmap_texture (MetaTextureMipmap *mipmap)
if (mipmap->invalid)
{
int n_planes, i;
n_planes = meta_multi_texture_get_n_planes (mipmap->base_texture);
if (!mipmap->pipeline)
{
MetaMultiTextureFormat format =
meta_multi_texture_get_format (mipmap->base_texture);
CoglSnippet *fragment_globals_snippet;
CoglSnippet *fragment_snippet;
mipmap->pipeline = cogl_pipeline_new (ctx);
cogl_pipeline_set_blend (mipmap->pipeline, "RGBA = ADD (SRC_COLOR, 0)", NULL);
cogl_pipeline_set_layer_filters (mipmap->pipeline, 0,
COGL_PIPELINE_FILTER_LINEAR,
COGL_PIPELINE_FILTER_LINEAR);
cogl_pipeline_set_blend (mipmap->pipeline,
"RGBA = ADD (SRC_COLOR, 0)",
NULL);
for (i = 0; i < n_planes; i++)
{
cogl_pipeline_set_layer_filters (mipmap->pipeline, i,
COGL_PIPELINE_FILTER_LINEAR,
COGL_PIPELINE_FILTER_LINEAR);
cogl_pipeline_set_layer_combine (mipmap->pipeline, i,
"RGBA = REPLACE(TEXTURE)",
NULL);
}
meta_multi_texture_format_get_snippets (format,
&fragment_globals_snippet,
&fragment_snippet);
cogl_pipeline_add_snippet (mipmap->pipeline, fragment_globals_snippet);
cogl_pipeline_add_snippet (mipmap->pipeline, fragment_snippet);
cogl_clear_object (&fragment_globals_snippet);
cogl_clear_object (&fragment_snippet);
}
for (i = 0; i < n_planes; i++)
{
CoglTexture *plane = meta_multi_texture_get_plane (mipmap->base_texture, i);
cogl_pipeline_set_layer_texture (mipmap->pipeline, i, plane);
}
cogl_pipeline_set_layer_texture (mipmap->pipeline, 0, mipmap->base_texture);
cogl_framebuffer_draw_textured_rectangle (mipmap->fb,
mipmap->pipeline,
0, 0, width, height,
@ -229,7 +265,7 @@ ensure_mipmap_texture (MetaTextureMipmap *mipmap)
* Return value: the COGL texture handle to use for painting, or
* %NULL if no base texture has yet been set.
*/
CoglTexture *
MetaMultiTexture *
meta_texture_mipmap_get_paint_texture (MetaTextureMipmap *mipmap)
{
g_return_val_if_fail (mipmap != NULL, NULL);

View File

@ -24,6 +24,7 @@
#define META_TEXTURE_MIPMAP_H
#include "clutter/clutter.h"
#include "meta/meta-multi-texture.h"
G_BEGIN_DECLS
@ -42,9 +43,9 @@ MetaTextureMipmap *meta_texture_mipmap_new (void);
void meta_texture_mipmap_free (MetaTextureMipmap *mipmap);
void meta_texture_mipmap_set_base_texture (MetaTextureMipmap *mipmap,
CoglTexture *texture);
MetaMultiTexture *texture);
CoglTexture *meta_texture_mipmap_get_paint_texture (MetaTextureMipmap *mipmap);
MetaMultiTexture *meta_texture_mipmap_get_paint_texture (MetaTextureMipmap *mipmap);
void meta_texture_mipmap_invalidate (MetaTextureMipmap *mipmap);

View File

@ -28,6 +28,7 @@
#include "clutter/clutter.h"
#include <meta/common.h>
#include <meta/meta-multi-texture.h>
G_BEGIN_DECLS
@ -45,7 +46,7 @@ void meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex,
gboolean create_mipmaps);
META_EXPORT
CoglTexture * meta_shaped_texture_get_texture (MetaShapedTexture *stex);
MetaMultiTexture * meta_shaped_texture_get_texture (MetaShapedTexture *stex);
META_EXPORT
void meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,

View File

@ -192,7 +192,7 @@ meta_wayland_actor_surface_real_sync_actor_state (MetaWaylandActorSurface *actor
{
CoglSnippet *snippet;
gboolean is_y_inverted;
CoglTexture *texture;
MetaMultiTexture *texture;
snippet = meta_wayland_buffer_create_snippet (buffer);
is_y_inverted = meta_wayland_buffer_is_y_inverted (buffer);

View File

@ -157,7 +157,7 @@ meta_wayland_buffer_realize (MetaWaylandBuffer *buffer)
buffer->egl_stream.stream = stream;
buffer->type = META_WAYLAND_BUFFER_TYPE_EGL_STREAM;
buffer->egl_stream.texture = COGL_TEXTURE (texture);
buffer->egl_stream.texture = meta_multi_texture_new_simple (COGL_TEXTURE (texture));
buffer->is_y_inverted = meta_wayland_egl_stream_is_y_inverted (stream);
return TRUE;
@ -328,7 +328,7 @@ shm_format_to_string (MetaDrmFormatBuf *format_buf,
static gboolean
shm_buffer_attach (MetaWaylandBuffer *buffer,
CoglTexture **texture,
MetaMultiTexture **texture,
GError **error)
{
MetaContext *context =
@ -340,7 +340,7 @@ shm_buffer_attach (MetaWaylandBuffer *buffer,
int stride, width, height;
CoglPixelFormat format;
CoglBitmap *bitmap;
CoglTexture *new_texture;
CoglTexture *new_cogl_tex;
MetaDrmFormatBuf format_buf;
shm_buffer = wl_shm_buffer_get (buffer->resource);
@ -362,15 +362,19 @@ shm_buffer_attach (MetaWaylandBuffer *buffer,
cogl_pixel_format_to_string (format));
if (*texture &&
cogl_texture_get_width (*texture) == width &&
cogl_texture_get_height (*texture) == height &&
_cogl_texture_get_format (*texture) == format)
meta_multi_texture_get_width (*texture) == width &&
meta_multi_texture_get_height (*texture) == height)
{
buffer->is_y_inverted = TRUE;
return TRUE;
CoglTexture *cogl_texture = meta_multi_texture_get_plane (*texture, 0);
if (_cogl_texture_get_format (cogl_texture) == format)
{
buffer->is_y_inverted = TRUE;
return TRUE;
}
}
cogl_clear_object (texture);
g_clear_object (texture);
wl_shm_buffer_begin_access (shm_buffer);
@ -380,11 +384,11 @@ shm_buffer_attach (MetaWaylandBuffer *buffer,
stride,
wl_shm_buffer_get_data (shm_buffer));
new_texture = COGL_TEXTURE (cogl_texture_2d_new_from_bitmap (bitmap));
new_cogl_tex = COGL_TEXTURE (cogl_texture_2d_new_from_bitmap (bitmap));
if (!cogl_texture_allocate (new_texture, error))
if (!cogl_texture_allocate (new_cogl_tex, error))
{
g_clear_pointer (&new_texture, cogl_object_unref);
g_clear_pointer (&new_cogl_tex, cogl_object_unref);
if (g_error_matches (*error, COGL_TEXTURE_ERROR, COGL_TEXTURE_ERROR_SIZE))
{
CoglTexture2DSliced *texture_sliced;
@ -394,10 +398,10 @@ shm_buffer_attach (MetaWaylandBuffer *buffer,
texture_sliced =
cogl_texture_2d_sliced_new_from_bitmap (bitmap,
COGL_TEXTURE_MAX_WASTE);
new_texture = COGL_TEXTURE (texture_sliced);
new_cogl_tex = COGL_TEXTURE (texture_sliced);
if (!cogl_texture_allocate (new_texture, error))
g_clear_pointer (&new_texture, cogl_object_unref);
if (!cogl_texture_allocate (new_cogl_tex, error))
g_clear_pointer (&new_cogl_tex, cogl_object_unref);
}
}
@ -405,10 +409,10 @@ shm_buffer_attach (MetaWaylandBuffer *buffer,
wl_shm_buffer_end_access (shm_buffer);
if (!new_texture)
if (!new_cogl_tex)
return FALSE;
*texture = new_texture;
*texture = meta_multi_texture_new_simple (new_cogl_tex);
buffer->is_y_inverted = TRUE;
return TRUE;
@ -416,7 +420,7 @@ shm_buffer_attach (MetaWaylandBuffer *buffer,
static gboolean
egl_image_buffer_attach (MetaWaylandBuffer *buffer,
CoglTexture **texture,
MetaMultiTexture **texture,
GError **error)
{
MetaContext *context =
@ -434,8 +438,8 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
if (buffer->egl_image.texture)
{
cogl_clear_object (texture);
*texture = cogl_object_ref (buffer->egl_image.texture);
g_clear_object (texture);
*texture = g_object_ref (buffer->egl_image.texture);
return TRUE;
}
@ -496,11 +500,11 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
if (!texture_2d)
return FALSE;
buffer->egl_image.texture = COGL_TEXTURE (texture_2d);
buffer->egl_image.texture = meta_multi_texture_new_simple (COGL_TEXTURE (texture_2d));
buffer->is_y_inverted = !!y_inverted;
cogl_clear_object (texture);
*texture = cogl_object_ref (buffer->egl_image.texture);
g_clear_object (texture);
*texture = g_object_ref (buffer->egl_image.texture);
return TRUE;
}
@ -508,7 +512,7 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
#ifdef HAVE_WAYLAND_EGLSTREAM
static gboolean
egl_stream_buffer_attach (MetaWaylandBuffer *buffer,
CoglTexture **texture,
MetaMultiTexture **texture,
GError **error)
{
MetaWaylandEglStream *stream = buffer->egl_stream.stream;
@ -518,8 +522,8 @@ egl_stream_buffer_attach (MetaWaylandBuffer *buffer,
if (!meta_wayland_egl_stream_attach (stream, error))
return FALSE;
cogl_clear_object (texture);
*texture = cogl_object_ref (buffer->egl_stream.texture);
g_clear_object (texture);
*texture = g_object_ref (buffer->egl_stream.texture);
return TRUE;
}
@ -565,8 +569,8 @@ clear_tainted_scanout_onscreens (MetaWaylandBuffer *buffer)
/**
* meta_wayland_buffer_attach:
* @buffer: a pointer to a #MetaWaylandBuffer
* @texture: (inout) (transfer full): a #CoglTexture representing the surface
* content
* @texture: (inout) (transfer full): a #MetaMultiTexture representing the
* surface content
* @error: return location for error or %NULL
*
* This function should be passed a pointer to the texture used to draw the
@ -583,7 +587,7 @@ clear_tainted_scanout_onscreens (MetaWaylandBuffer *buffer)
*/
gboolean
meta_wayland_buffer_attach (MetaWaylandBuffer *buffer,
CoglTexture **texture,
MetaMultiTexture **texture,
GError **error)
{
COGL_TRACE_BEGIN_SCOPED (MetaWaylandBufferAttach, "WaylandBuffer (attach)");
@ -675,7 +679,7 @@ meta_wayland_buffer_is_y_inverted (MetaWaylandBuffer *buffer)
static gboolean
process_shm_buffer_damage (MetaWaylandBuffer *buffer,
CoglTexture *texture,
MetaMultiTexture *texture,
cairo_region_t *region,
GError **error)
{
@ -683,6 +687,7 @@ process_shm_buffer_damage (MetaWaylandBuffer *buffer,
int i, n_rectangles;
gboolean set_texture_failed = FALSE;
CoglPixelFormat format;
CoglTexture *cogl_texture;
n_rectangles = cairo_region_num_rectangles (region);
@ -690,6 +695,7 @@ process_shm_buffer_damage (MetaWaylandBuffer *buffer,
shm_buffer_get_cogl_pixel_format (buffer, shm_buffer, &format);
g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, FALSE);
cogl_texture = meta_multi_texture_get_plane (texture, 0);
wl_shm_buffer_begin_access (shm_buffer);
@ -703,7 +709,7 @@ process_shm_buffer_damage (MetaWaylandBuffer *buffer,
bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0);
cairo_region_get_rectangle (region, i, &rect);
if (!_cogl_texture_set_region (texture,
if (!_cogl_texture_set_region (cogl_texture,
rect.width, rect.height,
format,
stride,
@ -724,7 +730,7 @@ process_shm_buffer_damage (MetaWaylandBuffer *buffer,
void
meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer,
CoglTexture *texture,
MetaMultiTexture *texture,
cairo_region_t *region)
{
gboolean res = FALSE;
@ -872,16 +878,16 @@ meta_wayland_buffer_finalize (GObject *object)
clear_tainted_scanout_onscreens (buffer);
g_clear_pointer (&buffer->tainted_scanout_onscreens, g_hash_table_unref);
g_clear_pointer (&buffer->egl_image.texture, cogl_object_unref);
g_clear_object (&buffer->egl_image.texture);
#ifdef HAVE_WAYLAND_EGLSTREAM
g_clear_pointer (&buffer->egl_stream.texture, cogl_object_unref);
g_clear_object (&buffer->egl_stream.texture);
g_clear_object (&buffer->egl_stream.stream);
#endif
g_clear_pointer (&buffer->dma_buf.texture, cogl_object_unref);
g_clear_object (&buffer->dma_buf.texture);
g_clear_object (&buffer->dma_buf.dma_buf);
g_clear_pointer (&buffer->single_pixel.single_pixel_buffer,
meta_wayland_single_pixel_buffer_free);
cogl_clear_object (&buffer->single_pixel.texture);
g_clear_object (&buffer->single_pixel.texture);
G_OBJECT_CLASS (meta_wayland_buffer_parent_class)->finalize (object);
}

View File

@ -29,6 +29,7 @@
#include <wayland-server.h>
#include "cogl/cogl.h"
#include "meta/meta-multi-texture.h"
#include "wayland/meta-wayland-types.h"
#include "wayland/meta-wayland-egl-stream.h"
#include "wayland/meta-wayland-dma-buf.h"
@ -61,24 +62,24 @@ struct _MetaWaylandBuffer
MetaWaylandBufferType type;
struct {
CoglTexture *texture;
MetaMultiTexture *texture;
} egl_image;
#ifdef HAVE_WAYLAND_EGLSTREAM
struct {
MetaWaylandEglStream *stream;
CoglTexture *texture;
MetaMultiTexture *texture;
} egl_stream;
#endif
struct {
MetaWaylandDmaBufBuffer *dma_buf;
CoglTexture *texture;
MetaMultiTexture *texture;
} dma_buf;
struct {
MetaWaylandSinglePixelBuffer *single_pixel_buffer;
CoglTexture *texture;
MetaMultiTexture *texture;
} single_pixel;
GHashTable *tainted_scanout_onscreens;
@ -94,14 +95,14 @@ struct wl_resource * meta_wayland_buffer_get_resource (MetaWaylandBuff
gboolean meta_wayland_buffer_is_realized (MetaWaylandBuffer *buffer);
gboolean meta_wayland_buffer_realize (MetaWaylandBuffer *buffer);
gboolean meta_wayland_buffer_attach (MetaWaylandBuffer *buffer,
CoglTexture **texture,
MetaMultiTexture **texture,
GError **error);
CoglSnippet * meta_wayland_buffer_create_snippet (MetaWaylandBuffer *buffer);
void meta_wayland_buffer_inc_use_count (MetaWaylandBuffer *buffer);
void meta_wayland_buffer_dec_use_count (MetaWaylandBuffer *buffer);
gboolean meta_wayland_buffer_is_y_inverted (MetaWaylandBuffer *buffer);
void meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer,
CoglTexture *texture,
MetaMultiTexture *texture,
cairo_region_t *region);
CoglScanout * meta_wayland_buffer_try_acquire_scanout (MetaWaylandBuffer *buffer,
CoglOnscreen *onscreen);

View File

@ -61,16 +61,17 @@ update_cursor_sprite_texture (MetaWaylandCursorSurface *cursor_surface)
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (META_WAYLAND_SURFACE_ROLE (cursor_surface));
MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (priv->cursor_sprite);
CoglTexture *texture;
MetaMultiTexture *texture;
if (!priv->cursor_renderer)
return;
texture = meta_wayland_surface_get_texture (surface);
if (texture)
if (texture && meta_multi_texture_is_simple (texture))
{
meta_cursor_sprite_set_texture (cursor_sprite,
texture,
meta_multi_texture_get_plane (texture, 0),
priv->hot_x * surface->scale,
priv->hot_y * surface->scale);
}

View File

@ -348,7 +348,7 @@ meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer *buffer,
CoglPixelFormat cogl_format;
EGLImageKHR egl_image;
CoglEglImageFlags flags;
CoglTexture2D *texture;
CoglTexture2D *cogl_texture;
#ifdef HAVE_NATIVE_BACKEND
MetaDrmFormatBuf format_buf;
#endif
@ -396,20 +396,20 @@ meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer *buffer,
return FALSE;
flags = COGL_EGL_IMAGE_FLAG_NO_GET_DATA;
texture = cogl_egl_texture_2d_new_from_image (cogl_context,
dma_buf->width,
dma_buf->height,
cogl_format,
egl_image,
flags,
error);
cogl_texture = cogl_egl_texture_2d_new_from_image (cogl_context,
dma_buf->width,
dma_buf->height,
cogl_format,
egl_image,
flags,
error);
meta_egl_destroy_image (egl, egl_display, egl_image, NULL);
if (!texture)
if (!cogl_texture)
return FALSE;
buffer->dma_buf.texture = COGL_TEXTURE (texture);
buffer->dma_buf.texture = meta_multi_texture_new_simple (COGL_TEXTURE (cogl_texture));
buffer->is_y_inverted = dma_buf->is_y_inverted;
return TRUE;
@ -417,14 +417,14 @@ meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer *buffer,
gboolean
meta_wayland_dma_buf_buffer_attach (MetaWaylandBuffer *buffer,
CoglTexture **texture,
MetaMultiTexture **texture,
GError **error)
{
if (!meta_wayland_dma_buf_realize_texture (buffer, error))
return FALSE;
cogl_clear_object (texture);
*texture = cogl_object_ref (buffer->dma_buf.texture);
g_clear_object (texture);
*texture = g_object_ref (buffer->dma_buf.texture);
return TRUE;
}

View File

@ -31,6 +31,7 @@
#include <glib-object.h>
#include "cogl/cogl.h"
#include "meta/meta-multi-texture.h"
#include "wayland/meta-wayland-types.h"
#define META_TYPE_WAYLAND_DMA_BUF_BUFFER (meta_wayland_dma_buf_buffer_get_type ())
@ -48,7 +49,7 @@ MetaWaylandDmaBufManager * meta_wayland_dma_buf_manager_new (MetaWaylandComposit
gboolean
meta_wayland_dma_buf_buffer_attach (MetaWaylandBuffer *buffer,
CoglTexture **texture,
MetaMultiTexture **texture,
GError **error);
MetaWaylandDmaBufBuffer *

View File

@ -108,7 +108,7 @@ single_pixel_buffer_manager_bind (struct wl_client *client,
gboolean
meta_wayland_single_pixel_buffer_attach (MetaWaylandBuffer *buffer,
CoglTexture **texture,
MetaMultiTexture **texture,
GError **error)
{
MetaContext *context =
@ -144,10 +144,11 @@ meta_wayland_single_pixel_buffer_attach (MetaWaylandBuffer *buffer,
if (!tex_2d)
return FALSE;
buffer->single_pixel.texture = COGL_TEXTURE (tex_2d);
buffer->single_pixel.texture =
meta_multi_texture_new_simple (COGL_TEXTURE (tex_2d));
cogl_clear_object (texture);
*texture = cogl_object_ref (buffer->single_pixel.texture);
g_clear_object (texture);
*texture = g_object_ref (buffer->single_pixel.texture);
return TRUE;
}

View File

@ -24,12 +24,13 @@
#include <glib.h>
#include "cogl/cogl.h"
#include "meta/meta-multi-texture.h"
#include "wayland/meta-wayland-types.h"
typedef struct _MetaWaylandSinglePixelBuffer MetaWaylandSinglePixelBuffer;
gboolean meta_wayland_single_pixel_buffer_attach (MetaWaylandBuffer *buffer,
CoglTexture **texture,
MetaMultiTexture **texture,
GError **error);
MetaWaylandSinglePixelBuffer * meta_wayland_single_pixel_buffer_from_buffer (MetaWaylandBuffer *buffer);

View File

@ -440,7 +440,7 @@ meta_wayland_surface_state_clear (MetaWaylandSurfaceState *state)
{
MetaWaylandFrameCallback *cb, *next;
cogl_clear_object (&state->texture);
g_clear_object (&state->texture);
g_clear_pointer (&state->surface_damage, cairo_region_destroy);
g_clear_pointer (&state->buffer_damage, cairo_region_destroy);
@ -490,7 +490,7 @@ meta_wayland_surface_state_merge_into (MetaWaylandSurfaceState *from,
to->newly_attached = TRUE;
to->buffer = g_steal_pointer (&from->buffer);
cogl_clear_object (&to->texture);
g_clear_object (&to->texture);
to->texture = g_steal_pointer (&from->texture);
}
@ -731,7 +731,7 @@ meta_wayland_surface_apply_state (MetaWaylandSurface *surface,
meta_wayland_buffer_dec_use_count (surface->buffer);
g_set_object (&surface->buffer, state->buffer);
cogl_clear_object (&surface->output_state.texture);
g_clear_object (&surface->output_state.texture);
surface->output_state.texture = g_steal_pointer (&state->texture);
/* If the newly attached buffer is going to be accessed directly without
@ -951,14 +951,14 @@ meta_wayland_surface_commit (MetaWaylandSurface *surface)
return;
}
pending->texture = cogl_object_ref (surface->protocol_state.texture);
pending->texture = g_object_ref (surface->protocol_state.texture);
g_object_ref (buffer);
meta_wayland_buffer_inc_use_count (buffer);
}
else if (pending->newly_attached)
{
cogl_clear_object (&surface->protocol_state.texture);
g_clear_object (&surface->protocol_state.texture);
}
if (meta_wayland_surface_is_synchronized (surface))
@ -1466,7 +1466,7 @@ meta_wayland_surface_finalize (GObject *object)
if (surface->buffer_held)
meta_wayland_buffer_dec_use_count (surface->buffer);
g_clear_pointer (&surface->output_state.texture, cogl_object_unref);
g_clear_object (&surface->output_state.texture);
g_clear_object (&surface->buffer);
if (surface->opaque_region)
@ -1518,7 +1518,7 @@ wl_surface_destructor (struct wl_resource *resource)
g_clear_pointer (&surface->wl_subsurface, wl_resource_destroy);
g_clear_pointer (&surface->protocol_state.subsurface_branch_node, g_node_destroy);
cogl_clear_object (&surface->protocol_state.texture);
g_clear_object (&surface->protocol_state.texture);
/*
* Any transactions referencing this surface will keep it alive until they get
@ -2105,7 +2105,7 @@ meta_wayland_surface_is_shortcuts_inhibited (MetaWaylandSurface *surface,
return g_hash_table_contains (surface->shortcut_inhibited_seats, seat);
}
CoglTexture *
MetaMultiTexture *
meta_wayland_surface_get_texture (MetaWaylandSurface *surface)
{
return surface->output_state.texture;
@ -2180,7 +2180,7 @@ meta_wayland_surface_get_buffer_width (MetaWaylandSurface *surface)
MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
if (buffer)
return cogl_texture_get_width (surface->output_state.texture);
return meta_multi_texture_get_width (surface->output_state.texture);
else
return 0;
}
@ -2191,7 +2191,7 @@ meta_wayland_surface_get_buffer_height (MetaWaylandSurface *surface)
MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
if (buffer)
return cogl_texture_get_height (surface->output_state.texture);
return meta_multi_texture_get_height (surface->output_state.texture);
else
return 0;
}

View File

@ -83,7 +83,7 @@ struct _MetaWaylandSurfaceState
/* wl_surface.attach */
gboolean newly_attached;
MetaWaylandBuffer *buffer;
CoglTexture *texture;
MetaMultiTexture *texture;
gulong buffer_destroy_handler_id;
int32_t dx;
int32_t dy;
@ -193,7 +193,7 @@ struct _MetaWaylandSurface
MetaWaylandSurface *parent;
GNode *subsurface_branch_node;
GNode *subsurface_leaf_node;
CoglTexture *texture;
MetaMultiTexture *texture;
} output_state, protocol_state;
/* Extension resources. */
@ -371,7 +371,7 @@ void meta_wayland_surface_restore_shortcuts (MetaWaylandSurface *
gboolean meta_wayland_surface_is_shortcuts_inhibited (MetaWaylandSurface *surface,
MetaWaylandSeat *seat);
CoglTexture * meta_wayland_surface_get_texture (MetaWaylandSurface *surface);
MetaMultiTexture * meta_wayland_surface_get_texture (MetaWaylandSurface *surface);
META_EXPORT_TEST
MetaSurfaceActor * meta_wayland_surface_get_actor (MetaWaylandSurface *surface);