Compare commits

...

8 Commits

Author SHA1 Message Date
Niels De Graef
919ae6b2b7 wip 2020-04-07 17:58:56 +02:00
Niels De Graef
1cb7146a2e WIP 2020-03-30 17:10:57 +02:00
Niels De Graef
b998b543f9 WIP 2020-03-30 17:10:57 +02:00
Niels De Graef
82149a3caa wip 2020-03-30 17:10:57 +02:00
Niels De Graef
ee17ddc18e wayland: Add support for YUV-based EGLimages 2020-03-30 17:10:57 +02:00
Niels De Graef
f11ca9cfaf multi-texture: Add API to have color conversion
Some pixel formats need to be converted to RGB first before they can be
composited onto the RGBA framebuffer. Since we have absolutely no
intention of doing this on the CPU (killing any kind of performance on
video), we write shaders to do this for us. MetaShapedTexture is then
extended to use this on its base pipeline.
2020-03-30 17:10:57 +02:00
Niels De Graef
c2e191fe3f 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.
2020-03-30 17:10:57 +02:00
Niels De Graef
65a3b13b2f compositor: Add MetaMultiTexture class
In future commits, we want to be able to handle more complex textures,
such as video frames which are encoded in a YUV-pixel format and have
multiple planes (which each map to a separate texture).

To accomplish this, we introduce a new object `MetaMultiTexture`: this
object can deal with more complex formats by handling multiple
`CoglTexture`s. In a later stage, it will be able to add `CoglSnippet`s
to perform e.g. pixel format conversion (for example from YUV to RGBA).
2020-03-30 17:07:58 +02:00
21 changed files with 1445 additions and 249 deletions

View File

@@ -103,6 +103,8 @@ _cogl_texture_2d_create_base (CoglContext *ctx,
_cogl_texture_init (tex, ctx, width, height, internal_format, loader,
&cogl_texture_2d_vtable);
g_warning ("cogl_texture_2d_vtable = %p", &cogl_texture_2d_vtable);
tex_2d->mipmaps_dirty = TRUE;
tex_2d->auto_mipmap = TRUE;
tex_2d->is_get_data_supported = TRUE;

View File

@@ -47,7 +47,7 @@ option('native_backend',
option('remote_desktop',
type: 'boolean',
value: true,
value: false,
description: 'Enable remote desktop and screen cast support'
)

View File

@@ -0,0 +1,480 @@
/*
* Authored By Niels De Graef <niels.degraef@barco.com>
*
* Copyright (C) 2018 Barco NV
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/**
* SECTION:meta-multi-texture-format
* @title: MetaMultiTextureFormat
* @short_description: A representation for complex pixel formats
*
* Some pixel formats that are used in the wild are a bit more complex than
* just ARGB and all its variants. For example: a component might be put in a
* different plane (i.e. at a different place in memory). Another example are
* formats that use Y, U, and V components rather than RGB; if we composit them
* onto an RGBA framebuffer, we have to make sure for example that these get
* converted to the right color format first (using e.g. a shader).
*/
#include "meta/meta-multi-texture-format.h"
#include <cogl/cogl.h>
#include <stdlib.h>
#include <string.h>
#define _YUV_TO_RGB(res, y, u, v) \
"vec4 " res ";\n" \
res ".r = (" y ") + 1.59765625 * (" v ");\n" \
res ".g = (" y ") - 0.390625 * (" u ") - 0.8125 * (" v ");\n" \
res ".b = (" y ") + 2.015625 * (" u ");\n" \
res ".a = 1.0;\n"
/* Shader for a single YUV plane */
#define YUV_TO_RGB_FUNC "meta_yuv_to_rgba"
static const char yuv_to_rgb_shader[] =
"vec4\n"
YUV_TO_RGB_FUNC " (vec2 UV)\n"
"{\n"
" vec4 orig_color = texture2D(cogl_sampler0, UV);\n"
" float y = 1.16438356 * (orig_color.r - 0.0625);\n"
" float u = orig_color.g - 0.5;\n"
" float v = orig_color.b - 0.5;\n"
_YUV_TO_RGB ("color", "y", "u", "v")
" return color;\n"
"}\n";
/* Shader for 1 Y-plane and 1 UV-plane */
#define Y_UV_TO_RGB_FUNC "meta_y_uv_to_rgba"
static const char y_uv_to_rgb_shader[] =
"vec4\n"
Y_UV_TO_RGB_FUNC "(vec2 UV)\n"
"{\n"
" float y = 1.1640625 * (texture2D (cogl_sampler0, UV).x - 0.0625);\n"
" vec2 uv = texture2D (cogl_sampler1, UV).rg;\n"
" uv -= 0.5;\n"
" float u = uv.x;\n"
" float v = uv.y;\n"
_YUV_TO_RGB ("color", "y", "u", "v")
" return color;\n"
"}\n";
/* Shader for 1 Y-plane, 1 U-plane and 1 V-plane */
#define Y_U_V_TO_RGB_FUNC "meta_y_u_v_to_rgba"
static const char y_u_v_to_rgb_shader[] =
"vec4\n"
Y_U_V_TO_RGB_FUNC "(vec2 UV)\n"
"{\n"
" float y = 1.16438356 * (texture2D(cogl_sampler0, UV).x - 0.0625);\n"
" float u = texture2D(cogl_sampler1, UV).x - 0.5;\n"
" float v = texture2D(cogl_sampler2, UV).x - 0.5;\n"
_YUV_TO_RGB ("color", "y", "u", "v")
" return color;\n"
"}\n";
typedef struct _MetaMultiTextureFormatInfo
{
MetaMultiTextureFormat multi_format;
uint8_t n_planes;
/* Per plane-information */
uint8_t bpp[COGL_PIXEL_FORMAT_MAX_PLANES]; /* Bytes per pixel (without subsampling) */
uint8_t hsub[COGL_PIXEL_FORMAT_MAX_PLANES]; /* horizontal subsampling */
uint8_t vsub[COGL_PIXEL_FORMAT_MAX_PLANES]; /* vertical subsampling */
CoglPixelFormat subformats[COGL_PIXEL_FORMAT_MAX_PLANES]; /* influences how we deal with it on a GL level */
/* Shaders */
const char *rgb_shaderfunc; /* Shader name to convert to RGBA (or NULL) */
const char *rgb_shader; /* Shader to convert to RGBA (or NULL) */
} MetaMultiTextureFormatInfo;
/* NOTE: The actual enum values are used as the index, so you don't need to
* loop over the table */
static MetaMultiTextureFormatInfo multi_format_table[] = {
/* Simple */
{
.n_planes = 1,
.bpp = { 4 },
.hsub = { 1 },
.vsub = { 1 },
.subformats = { COGL_PIXEL_FORMAT_ANY },
.rgb_shaderfunc = NULL,
.rgb_shader = NULL,
},
/* Packed YUV */
{ /* YUYV */
.n_planes = 1,
.bpp = { 4 },
.hsub = { 1 },
.vsub = { 1 },
.subformats = { COGL_PIXEL_FORMAT_ARGB_8888 },
.rgb_shaderfunc = YUV_TO_RGB_FUNC,
.rgb_shader = yuv_to_rgb_shader,
},
{ /* YVYU */
.n_planes = 1,
.bpp = { 4 },
.hsub = { 1 },
.vsub = { 1 },
.subformats = { COGL_PIXEL_FORMAT_ARGB_8888 },
.rgb_shaderfunc = YUV_TO_RGB_FUNC,
.rgb_shader = yuv_to_rgb_shader,
},
{ /* UYVY */
.n_planes = 1,
.bpp = { 4 },
.hsub = { 1 },
.vsub = { 1 },
.subformats = { COGL_PIXEL_FORMAT_ARGB_8888 },
.rgb_shaderfunc = YUV_TO_RGB_FUNC,
.rgb_shader = yuv_to_rgb_shader,
},
{ /* VYUY */
.n_planes = 1,
.bpp = { 4 },
.hsub = { 1 },
.vsub = { 1 },
.subformats = { COGL_PIXEL_FORMAT_ARGB_8888 },
.rgb_shaderfunc = YUV_TO_RGB_FUNC,
.rgb_shader = yuv_to_rgb_shader,
},
{ /* AYUV */
.n_planes = 1,
.bpp = { 4 },
.hsub = { 1 },
.vsub = { 1 },
.subformats = { COGL_PIXEL_FORMAT_ARGB_8888 },
.rgb_shaderfunc = YUV_TO_RGB_FUNC,
.rgb_shader = yuv_to_rgb_shader,
},
/* 2 plane RGB + A */
{ /* XRGB8888_A8 */
.n_planes = 2,
.bpp = { 4, 1 },
.hsub = { 1, 1 },
.vsub = { 1, 1 },
.subformats = { COGL_PIXEL_FORMAT_ARGB_8888, COGL_PIXEL_FORMAT_A_8 },
.rgb_shaderfunc = NULL,
.rgb_shader = NULL,
},
{ /* XBGR8888_A8 */
.n_planes = 2,
.bpp = { 4, 1 },
.hsub = { 1, 1 },
.vsub = { 1, 1 },
.subformats = { COGL_PIXEL_FORMAT_ABGR_8888, COGL_PIXEL_FORMAT_A_8 },
.rgb_shaderfunc = NULL,
.rgb_shader = NULL,
},
{ /* RGBX8888_A8 */
.n_planes = 2,
.bpp = { 4, 1 },
.hsub = { 1, 1 },
.vsub = { 1, 1 },
.subformats = { COGL_PIXEL_FORMAT_RGBA_8888, COGL_PIXEL_FORMAT_A_8 },
.rgb_shaderfunc = NULL,
.rgb_shader = NULL,
},
{ /* BGRX8888_A8 */
.n_planes = 2,
.bpp = { 4, 1 },
.hsub = { 1, 1 },
.vsub = { 1, 1 },
.subformats = { COGL_PIXEL_FORMAT_BGRA_8888, COGL_PIXEL_FORMAT_A_8 },
.rgb_shaderfunc = NULL,
.rgb_shader = NULL,
},
{ /* RGB888_A8 */
.n_planes = 2,
.bpp = { 3, 1 },
.hsub = { 1, 1 },
.vsub = { 1, 1 },
.subformats = { COGL_PIXEL_FORMAT_RGB_888, COGL_PIXEL_FORMAT_A_8 },
.rgb_shaderfunc = NULL,
.rgb_shader = NULL,
},
{ /* BGR888_A8 */
.n_planes = 2,
.bpp = { 3, 1 },
.hsub = { 1, 1 },
.vsub = { 1, 1 },
.subformats = { COGL_PIXEL_FORMAT_BGR_888, COGL_PIXEL_FORMAT_A_8 },
.rgb_shaderfunc = NULL,
.rgb_shader = NULL,
},
{ /* RGB565_A8 */
.n_planes = 2,
.bpp = { 2, 1 },
.hsub = { 1, 1 },
.vsub = { 1, 1 },
.subformats = { COGL_PIXEL_FORMAT_RGB_565, COGL_PIXEL_FORMAT_A_8 },
.rgb_shaderfunc = NULL,
.rgb_shader = NULL,
},
{ /* BGR565_A8 */
.n_planes = 2,
.bpp = { 2, 1 },
.hsub = { 1, 1 },
.vsub = { 1, 1 },
.subformats = { COGL_PIXEL_FORMAT_RGB_565, COGL_PIXEL_FORMAT_A_8 },
.rgb_shaderfunc = NULL,
.rgb_shader = NULL,
},
/* 2 plane YUV */
{ /* NV12 */
.n_planes = 2,
.bpp = { 1, 2 },
.hsub = { 1, 2 },
.vsub = { 1, 2 },
.subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_RG_88 },
.rgb_shaderfunc = Y_UV_TO_RGB_FUNC,
.rgb_shader = y_uv_to_rgb_shader,
},
{ /* NV21 */
.n_planes = 2,
.bpp = { 1, 2 },
.hsub = { 1, 2 },
.vsub = { 1, 2 },
.subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_RG_88 },
.rgb_shaderfunc = Y_UV_TO_RGB_FUNC,
.rgb_shader = y_uv_to_rgb_shader,
},
{ /* NV16 */
.n_planes = 2,
.bpp = { 1, 2 },
.hsub = { 1, 2 },
.vsub = { 1, 1 },
.subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_RG_88 },
.rgb_shaderfunc = Y_UV_TO_RGB_FUNC,
.rgb_shader = y_uv_to_rgb_shader,
},
{ /* NV61 */
.n_planes = 2,
.bpp = { 1, 2 },
.hsub = { 1, 2 },
.vsub = { 1, 1 },
.subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_RG_88 },
.rgb_shaderfunc = Y_UV_TO_RGB_FUNC,
.rgb_shader = y_uv_to_rgb_shader,
},
{ /* NV24 */
.n_planes = 2,
.bpp = { 1, 2 },
.hsub = { 1, 1 },
.vsub = { 1, 1 },
.subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_RG_88 },
.rgb_shaderfunc = Y_UV_TO_RGB_FUNC,
.rgb_shader = y_uv_to_rgb_shader,
},
{ /* NV42 */
.n_planes = 2,
.bpp = { 1, 2 },
.hsub = { 1, 1 },
.vsub = { 1, 1 },
.subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_RG_88 },
.rgb_shaderfunc = Y_UV_TO_RGB_FUNC,
.rgb_shader = y_uv_to_rgb_shader,
},
/* 3 plane YUV */
{ /* YUV410 */
.n_planes = 3,
.bpp = { 1, 1, 1 },
.hsub = { 1, 4, 4 },
.vsub = { 1, 4, 4 },
.subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8 },
.rgb_shaderfunc = Y_U_V_TO_RGB_FUNC,
.rgb_shader = y_u_v_to_rgb_shader,
},
{ /* YVU410 */
.n_planes = 3,
.bpp = { 1, 1, 1 },
.hsub = { 1, 4, 4 },
.vsub = { 1, 4, 4 },
.subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8 },
.rgb_shaderfunc = Y_U_V_TO_RGB_FUNC,
.rgb_shader = y_u_v_to_rgb_shader,
},
{ /* YUV411 */
.n_planes = 3,
.bpp = { 1, 1, 1 },
.hsub = { 1, 4, 4 },
.vsub = { 1, 1, 1 },
.subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8 },
.rgb_shaderfunc = Y_U_V_TO_RGB_FUNC,
.rgb_shader = y_u_v_to_rgb_shader,
},
{ /* YVU411 */
.n_planes = 3,
.bpp = { 1, 1, 1 },
.hsub = { 1, 4, 4 },
.vsub = { 1, 1, 1 },
.subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8 },
.rgb_shaderfunc = Y_U_V_TO_RGB_FUNC,
.rgb_shader = y_u_v_to_rgb_shader,
},
{ /* YUV420 */
.n_planes = 3,
.bpp = { 1, 1, 1 },
.hsub = { 1, 2, 2 },
.vsub = { 1, 2, 2 },
.subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8 },
.rgb_shaderfunc = Y_U_V_TO_RGB_FUNC,
.rgb_shader = y_u_v_to_rgb_shader,
},
{ /* YVU420 */
.n_planes = 3,
.bpp = { 1, 1, 1 },
.hsub = { 1, 2, 2 },
.vsub = { 1, 2, 2 },
.subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8 },
.rgb_shaderfunc = Y_U_V_TO_RGB_FUNC,
.rgb_shader = y_u_v_to_rgb_shader,
},
{ /* YUV422 */
.n_planes = 3,
.bpp = { 1, 1, 1 },
.hsub = { 1, 2, 2 },
.vsub = { 1, 1, 1 },
.subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8 },
.rgb_shaderfunc = Y_U_V_TO_RGB_FUNC,
.rgb_shader = y_u_v_to_rgb_shader,
},
{ /* YVU422 */
.n_planes = 3,
.bpp = { 1, 1, 1 },
.hsub = { 1, 2, 2 },
.vsub = { 1, 1, 1 },
.subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8 },
.rgb_shaderfunc = Y_U_V_TO_RGB_FUNC,
.rgb_shader = y_u_v_to_rgb_shader,
},
{ /* YUV444 */
.n_planes = 3,
.bpp = { 1, 1, 1 },
.hsub = { 1, 1, 1 },
.vsub = { 1, 1, 1 },
.subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8 },
.rgb_shaderfunc = Y_U_V_TO_RGB_FUNC,
.rgb_shader = y_u_v_to_rgb_shader,
},
{ /* YVU444 */
.n_planes = 3,
.bpp = { 1, 1, 1 },
.hsub = { 1, 1, 1 },
.vsub = { 1, 1, 1 },
.subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8 },
.rgb_shaderfunc = Y_U_V_TO_RGB_FUNC,
.rgb_shader = y_u_v_to_rgb_shader,
},
};
void
meta_multi_texture_format_get_bytes_per_pixel (MetaMultiTextureFormat format,
uint8_t *bpp_out)
{
size_t i;
g_return_if_fail (format < G_N_ELEMENTS (multi_format_table));
for (i = 0; i < multi_format_table[format].n_planes; i++)
bpp_out[i] = multi_format_table[format].bpp[i];
}
int
meta_multi_texture_format_get_n_planes (MetaMultiTextureFormat format)
{
g_return_val_if_fail (format < G_N_ELEMENTS (multi_format_table), 0);
return multi_format_table[format].n_planes;
}
void
meta_multi_texture_format_get_subsampling_factors (MetaMultiTextureFormat format,
uint8_t *horizontal_factors,
uint8_t *vertical_factors)
{
size_t i;
g_return_if_fail (format < G_N_ELEMENTS (multi_format_table));
for (i = 0; i < multi_format_table[format].n_planes; i++)
{
horizontal_factors[i] = multi_format_table[format].hsub[i];
vertical_factors[i] = multi_format_table[format].vsub[i];
}
}
void
meta_multi_texture_format_get_subformats (MetaMultiTextureFormat format,
CoglPixelFormat *formats_out)
{
size_t i;
g_return_if_fail (format < G_N_ELEMENTS (multi_format_table));
for (i = 0; i < multi_format_table[format].n_planes; i++)
formats_out[i] = multi_format_table[format].subformats[i];
}
gboolean
meta_multi_texture_format_needs_shaders (MetaMultiTextureFormat format)
{
g_return_val_if_fail (format < G_N_ELEMENTS (multi_format_table), FALSE);
return multi_format_table[format].rgb_shaderfunc != NULL;
}
gboolean
meta_multi_texture_format_get_snippets (MetaMultiTextureFormat format,
CoglSnippet **vertex_snippet,
CoglSnippet **fragment_snippet,
CoglSnippet **layer_snippet)
{
const char *shader_func;
const char *shader_impl;
g_autofree char *layer_hook = NULL;
g_return_val_if_fail (format < G_N_ELEMENTS (multi_format_table), FALSE);
/* Get the function name; bail out early if we don't need a shader */
shader_func = multi_format_table[format].rgb_shaderfunc;
if (shader_func == NULL)
return FALSE;
shader_impl = multi_format_table[format].rgb_shader;
/* Make sure we actually call the function */
layer_hook = g_strdup_printf ("cogl_layer = %s(cogl_tex_coord0_in.st);\n",
shader_func);
if (vertex_snippet)
*vertex_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX_GLOBALS,
shader_impl,
NULL);
if (fragment_snippet)
*fragment_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT_GLOBALS,
shader_impl,
NULL);
if (layer_snippet)
*layer_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_LAYER_FRAGMENT,
NULL,
layer_hook);
return TRUE;
}

View File

@@ -0,0 +1,285 @@
/*
* Authored By Niels De Graef <niels.degraef@barco.com>
*
* Copyright (C) 2018 Barco NV
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/**
* SECTION:meta-multi-texture
* @title: MetaMultiTexture
* @short_description: A texture that can have multiple subtextures.
*
* #MetaMultiTexture allows one to deal with non-trivial formats that
* have multiple planes, requires subsampling and/or aren't in RGB. A common
* example of this are decoded video frames, which often use something in the
* YUV colorspace, combined with subsampling.
*
* The basic idea of a #MetaMultiTexture is the following:
* - Each subtextures is represented by a separate #CoglTexture. That means
* that you should add each of these planes as a layer to your #CoglPipeline.
* - When dealing with a color space that is not RGB, you can ask the
* #MetaMultiTexture to create a shader for you that does the conversion
* in the GPU.
* - In case you need to deal with memory access in a format with subsampling,
* you can use meta_multi_texture_get_width() and its analogous version
* for the height to get the correct size of the texture.
*/
#include "meta/meta-multi-texture.h"
#include "meta/meta-enum-types.h"
struct _MetaMultiTexture
{
GObject parent_instance;
MetaMultiTextureFormat format;
guint n_subtextures;
CoglTexture **subtextures;
};
G_DEFINE_TYPE (MetaMultiTexture, meta_multi_texture, G_TYPE_OBJECT);
/**
* meta_multi_texture_get_format:
* @self: a #MetaMultiTexture
*
* Returns the #MetaMultiTextureFormat that is used by this texture.
*
* Returns: The texture format that is used by this #MetaMultiTexture.
*/
MetaMultiTextureFormat
meta_multi_texture_get_format (MetaMultiTexture *self)
{
g_return_val_if_fail (META_IS_MULTI_TEXTURE (self), META_MULTI_TEXTURE_FORMAT_SIMPLE);
return self->format;
}
/**
* meta_multi_texture_is_simple:
* @self: a #MetaMultiTexture
*
* A small function that checks whether the given multi texture uses a "simple"
* format, i.e. one that can be represented by a #CoglPixelFormat.
*
* Returns: Whether the texture format is #META_MULTI_TEXTURE_FORMAT_SIMPLE
*/
gboolean
meta_multi_texture_is_simple (MetaMultiTexture *self)
{
g_return_val_if_fail (META_IS_MULTI_TEXTURE (self), FALSE);
return self->format == META_MULTI_TEXTURE_FORMAT_SIMPLE;
}
/**
* meta_multi_texture_get_n_subtexture:
* @self: a #MetaMultiTexture
*
* Returns the number of subtextures for this texture. For example, simple RGB
* textures will have a single subtexture, while some more convoluted formats
* like NV12 and YUV 4:4:4 can have 2 and 3 subtextures respectively.
*
* Returns: The number of subtextures in this #MetaMultiTexture.
*/
guint
meta_multi_texture_get_n_subtextures (MetaMultiTexture *self)
{
g_return_val_if_fail (META_IS_MULTI_TEXTURE (self), 0);
return self->n_subtextures;
}
/**
* meta_multi_texture_get_subtexture:
* @self: a #MetaMultiTexture
* @index: the index of the subtexture
*
* Returns the n'th subtexture of the #MetaMultiTexture. Note that it's a
* programming error to use with an index larger than
* meta_multi_texture_get_n_subtextures().
*
* Returns: (transfer none): The subtexture at the given @index.
*/
CoglTexture *
meta_multi_texture_get_subtexture (MetaMultiTexture *self, guint index)
{
g_return_val_if_fail (META_IS_MULTI_TEXTURE (self), 0);
g_return_val_if_fail (index < self->n_subtextures, NULL);
return self->subtextures[index];
}
/**
* meta_multi_texture_get_width:
* @self: a #MetaMultiTexture
*
* Returns the width of the #MetaMultiTexture. Prefer this over calling
* cogl_texture_get_width() on one of the textures, as that might give a
* different size when dealing with subsampling.
*
* Returns: The width of the texture.
*/
int
meta_multi_texture_get_width (MetaMultiTexture *self)
{
g_return_val_if_fail (META_IS_MULTI_TEXTURE (self), 0);
return cogl_texture_get_width (self->subtextures[0]);
}
/**
* meta_multi_texture_get_height:
* @self: a #MetaMultiTexture
*
* Returns the height of the #MetaMultiTexture. Prefer this over calling
* cogl_texture_get_height() on one of the textures, as that might give a
* different size when dealing with subsampling.
*
* Returns: The height of the texture.
*/
int
meta_multi_texture_get_height (MetaMultiTexture *self)
{
g_return_val_if_fail (META_IS_MULTI_TEXTURE (self), 0);
return cogl_texture_get_height (self->subtextures[0]);
}
static void
meta_multi_texture_finalize (GObject *object)
{
MetaMultiTexture *self = META_MULTI_TEXTURE (object);
int i;
for (i = 0; i < self->n_subtextures; i++)
cogl_clear_object (&self->subtextures[i]);
g_free (self->subtextures);
G_OBJECT_CLASS (meta_multi_texture_parent_class)->finalize (object);
}
static void
meta_multi_texture_init (MetaMultiTexture *self)
{
}
static void
meta_multi_texture_class_init (MetaMultiTextureClass *klass)
{
GObjectClass *gobj_class = G_OBJECT_CLASS (klass);
gobj_class->finalize = meta_multi_texture_finalize;
}
/**
* meta_multi_texture_new:
* @format: The format of the #MetaMultiTexture
* @subtextures: (transfer full): The actual subtextures of the texture
* @n_subtextures: The number of subtextures
*
* Creates a #MetaMultiTexture with the given @format. Each of the
* #CoglTexture<!-- -->s represents a subtexture.
*
* Returns: (transfer full): A new #MetaMultiTexture. Use g_object_unref() when
* you're done with it.
*/
MetaMultiTexture *
meta_multi_texture_new (MetaMultiTextureFormat format,
CoglTexture **subtextures,
guint n_subtextures)
{
MetaMultiTexture *self;
g_return_val_if_fail (subtextures != NULL, NULL);
g_return_val_if_fail (n_subtextures > 0, NULL);
self = g_object_new (META_TYPE_MULTI_TEXTURE, NULL);
self->format = format;
self->n_subtextures = n_subtextures;
self->subtextures = subtextures;
return self;
}
/**
* meta_multi_texture_new_simple:
* @subtexture: (transfer full): The single subtexture of the texture
*
* Creates a #MetaMultiTexture for a "simple" texture, i.e. with only one
* subtexture, in a format that can be represented using #CoglPixelFormat.
*
* Returns: (transfer full): A new #MetaMultiTexture. Use g_object_unref() when
* you're done with it.
*/
MetaMultiTexture *
meta_multi_texture_new_simple (CoglTexture *subtexture)
{
MetaMultiTexture *self;
g_return_val_if_fail (subtexture != NULL, NULL);
self = g_object_new (META_TYPE_MULTI_TEXTURE, NULL);
self->format = META_MULTI_TEXTURE_FORMAT_SIMPLE;
self->n_subtextures = 1;
self->subtextures = g_malloc (sizeof (CoglTexture *));
self->subtextures[0] = subtexture;
return self;
}
/**
* meta_multi_texture_to_string:
* @self: a #MetaMultiTexture
*
* Returns a string representation of @self, useful for debugging purposes.
*
* Returns: (transfer full): A string representation of @self. Use g_free() when
* done with it.
*/
char *
meta_multi_texture_to_string (MetaMultiTexture *self)
{
g_autoptr(GString) str = NULL;
g_autofree char *format_str = NULL;
g_autofree char *ret = NULL;
uint8_t i;
str = g_string_new ("");
g_string_append_printf (str, "MetaMultiTexture (%p) {\n", self);
format_str = g_enum_to_string (META_TYPE_MULTI_TEXTURE_FORMAT, self->format);
g_string_append_printf (str, " .format = %s;\n", format_str);
g_string_append_printf (str, " .n_subtextures = %u;\n", self->n_subtextures);
g_string_append (str, " .subtextures = {\n");
for (i = 0; i < self->n_subtextures; i++)
{
CoglTexture *subtexture = self->subtextures[i];
CoglPixelFormat subtexture_format = _cogl_texture_get_format (subtexture);
g_string_append_printf (str, " (%p) { .format = %s },\n",
subtexture,
cogl_pixel_format_to_string (subtexture_format));
}
g_string_append (str, " }\n");
g_string_append (str, "}");
ret = g_string_free (g_steal_pointer (&str), FALSE);
return g_steal_pointer (&ret);
}

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

@@ -74,7 +74,7 @@ struct _MetaShapedTexture
MetaTextureTower *paint_tower;
CoglTexture *texture;
MetaMultiTexture *texture;
CoglTexture *mask_texture;
CoglSnippet *snippet;
@@ -249,24 +249,31 @@ static CoglPipeline *
get_base_pipeline (MetaShapedTexture *stex,
CoglContext *ctx)
{
guint i, n_subtextures;
MetaMultiTextureFormat format;
CoglPipeline *pipeline;
CoglMatrix matrix;
if (stex->base_pipeline)
return stex->base_pipeline;
/* We'll add as many layers as there are subtextures in the multi texture,
* plus an extra one for the mask */
n_subtextures = meta_multi_texture_get_n_subtextures (stex->texture);
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);
for (i = 0; i < n_subtextures; 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);
}
cogl_matrix_init_identity (&matrix);
/* Apply Y-inversion if necessary */
if (!stex->is_y_inverted)
{
cogl_matrix_scale (&matrix, 1, -1, 1);
@@ -274,6 +281,7 @@ get_base_pipeline (MetaShapedTexture *stex,
cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix);
}
/* Apply transformation if needed */
if (stex->transform != META_MONITOR_TRANSFORM_NORMAL)
{
graphene_euler_t euler;
@@ -316,6 +324,7 @@ get_base_pipeline (MetaShapedTexture *stex,
cogl_matrix_translate (&matrix, -0.5, -0.5, 0.0);
}
/* Apply viewport scaling if neeed */
if (stex->has_viewport_src_rect)
{
float scaled_tex_width = stex->tex_width / (float) stex->buffer_scale;
@@ -348,9 +357,29 @@ get_base_pipeline (MetaShapedTexture *stex,
0);
}
cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix);
cogl_pipeline_set_layer_matrix (pipeline, 1, &matrix);
for (i = 0; i < n_subtextures + 1; i++)
cogl_pipeline_set_layer_matrix (pipeline, i, &matrix);
/* Add color conversion shaders if needed */
format = meta_multi_texture_get_format (stex->texture);
if (meta_multi_texture_format_needs_shaders (format))
{
CoglSnippet *vertex_snippet;
CoglSnippet *fragment_snippet;
CoglSnippet *layer_snippet;
meta_multi_texture_format_get_snippets (format,
&vertex_snippet,
&fragment_snippet,
&layer_snippet);
cogl_pipeline_add_snippet (pipeline, vertex_snippet);
cogl_pipeline_add_snippet (pipeline, fragment_snippet);
for (i = 0; i < n_subtextures; i++)
cogl_pipeline_add_layer_snippet (pipeline, i, layer_snippet);
}
/* And custom external shaders (e.g. for EGLStreams) */
if (stex->snippet)
cogl_pipeline_add_layer_snippet (pipeline, 0, stex->snippet);
@@ -371,12 +400,14 @@ get_masked_pipeline (MetaShapedTexture *stex,
CoglContext *ctx)
{
CoglPipeline *pipeline;
guint n_subtextures;
if (stex->masked_pipeline)
return stex->masked_pipeline;
pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
cogl_pipeline_set_layer_combine (pipeline, 1,
n_subtextures = meta_multi_texture_get_n_subtextures (stex->texture);
cogl_pipeline_set_layer_combine (pipeline, n_subtextures,
"RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
NULL);
@@ -457,18 +488,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
{
@@ -490,7 +521,7 @@ set_cogl_texture (MetaShapedTexture *stex,
* damage. */
if (stex->create_mipmaps)
meta_texture_tower_set_base_texture (stex->paint_tower, cogl_tex);
meta_texture_tower_set_base_texture (stex->paint_tower, multi_tex);
}
static gboolean
@@ -522,7 +553,7 @@ static void
do_paint_content (MetaShapedTexture *stex,
ClutterPaintNode *root_node,
ClutterPaintContext *paint_context,
CoglTexture *paint_tex,
MetaMultiTexture *paint_tex,
ClutterActorBox *alloc,
uint8_t opacity)
{
@@ -534,6 +565,7 @@ do_paint_content (MetaShapedTexture *stex,
CoglPipelineFilter filter;
CoglFramebuffer *framebuffer;
int sample_width, sample_height;
guint n_subtextures;
ensure_size_valid (stex);
@@ -565,8 +597,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);
@@ -609,6 +641,8 @@ do_paint_content (MetaShapedTexture *stex,
}
}
n_subtextures = meta_multi_texture_get_n_subtextures (paint_tex);
/* First, paint the unblended parts, which are part of the opaque region. */
if (use_opaque_region)
{
@@ -620,8 +654,14 @@ do_paint_content (MetaShapedTexture *stex,
CoglPipeline *opaque_pipeline;
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);
for (i = 0; i < n_subtextures; i++)
{
CoglTexture *subtexture = meta_multi_texture_get_subtexture (paint_tex, i);
cogl_pipeline_set_layer_texture (opaque_pipeline, i, subtexture);
cogl_pipeline_set_layer_filters (opaque_pipeline, i, filter, filter);
}
n_rects = cairo_region_num_rectangles (stex->opaque_region);
for (i = 0; i < n_rects; i++)
@@ -648,6 +688,7 @@ do_paint_content (MetaShapedTexture *stex,
if (!blended_tex_region || !cairo_region_is_empty (blended_tex_region))
{
CoglPipeline *blended_pipeline;
guint i;
if (stex->mask_texture == NULL)
{
@@ -656,16 +697,20 @@ do_paint_content (MetaShapedTexture *stex,
else
{
blended_pipeline = get_masked_pipeline (stex, ctx);
cogl_pipeline_set_layer_texture (blended_pipeline, 1, stex->mask_texture);
cogl_pipeline_set_layer_filters (blended_pipeline, 1, filter, filter);
cogl_pipeline_set_layer_texture (blended_pipeline, n_subtextures, stex->mask_texture);
cogl_pipeline_set_layer_filters (blended_pipeline, n_subtextures, filter, filter);
}
cogl_pipeline_set_layer_texture (blended_pipeline, 0, paint_tex);
cogl_pipeline_set_layer_filters (blended_pipeline, 0, filter, filter);
for (i = 0; i < n_subtextures; i++)
{
CoglTexture *subtexture = meta_multi_texture_get_subtexture (paint_tex, i);
CoglColor color;
cogl_color_init_from_4ub (&color, opacity, opacity, opacity, opacity);
cogl_pipeline_set_color (blended_pipeline, &color);
cogl_pipeline_set_layer_texture (blended_pipeline, i, subtexture);
cogl_pipeline_set_layer_filters (blended_pipeline, i, filter, filter);
}
cogl_pipeline_set_color4ub (blended_pipeline,
opacity, opacity, opacity, opacity);
if (blended_tex_region)
{
@@ -702,11 +747,11 @@ do_paint_content (MetaShapedTexture *stex,
g_clear_pointer (&blended_tex_region, cairo_region_destroy);
}
static CoglTexture *
select_texture_for_paint (MetaShapedTexture *stex,
static MetaMultiTexture *
select_texture_for_paint (MetaShapedTexture *stex,
ClutterPaintContext *paint_context)
{
CoglTexture *texture = NULL;
MetaMultiTexture *texture = NULL;
int64_t now;
if (!stex->texture)
@@ -754,7 +799,7 @@ meta_shaped_texture_paint_content (ClutterContent *content,
{
MetaShapedTexture *stex = META_SHAPED_TEXTURE (content);
ClutterActorBox alloc;
CoglTexture *paint_tex = NULL;
MetaMultiTexture *paint_tex = NULL;
uint8_t opacity;
/* The GL EXT_texture_from_pixmap extension does allow for it to be
@@ -817,7 +862,7 @@ meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex,
if (create_mipmaps != stex->create_mipmaps)
{
CoglTexture *base_texture;
MetaMultiTexture *base_texture;
stex->create_mipmaps = create_mipmaps;
base_texture = create_mipmaps ? stex->texture : NULL;
meta_texture_tower_set_base_texture (stex->paint_tower, base_texture);
@@ -964,18 +1009,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);
}
/**
@@ -1016,11 +1061,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;
}
/**
@@ -1058,13 +1103,19 @@ 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))
/* FIXME: for now we don't support alpha (except simple textures) */
if (meta_multi_texture_get_n_subtextures (multi_texture) > 1)
return FALSE;
cogl_texture = meta_multi_texture_get_subtexture (multi_texture, 0);
switch (cogl_texture_get_components (cogl_texture))
{
case COGL_TEXTURE_COMPONENTS_A:
case COGL_TEXTURE_COMPONENTS_RGBA:
@@ -1082,12 +1133,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;
@@ -1179,7 +1230,13 @@ meta_shaped_texture_reset_viewport_dst_size (MetaShapedTexture *stex)
static gboolean
should_get_via_offscreen (MetaShapedTexture *stex)
{
if (!cogl_texture_is_get_data_supported (stex->texture))
CoglTexture *cogl_texture;
if (meta_multi_texture_get_n_subtextures (stex->texture) > 1)
return FALSE;
cogl_texture = meta_multi_texture_get_subtexture (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)
@@ -1322,9 +1379,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;
ensure_size_valid (stex);
@@ -1367,6 +1422,9 @@ meta_shaped_texture_get_image (MetaShapedTexture *stex,
image_height);
}
/* We know that we only have 1 subtexture at this point */
texture = meta_multi_texture_get_subtexture (stex->texture, 0);
if (image_clip)
texture = cogl_texture_new_from_sub_texture (texture,
image_clip->x,

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!\n");
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
@@ -192,6 +192,7 @@ meta_surface_actor_x11_process_damage (MetaSurfaceActor *actor,
int x, int y, int width, int height)
{
MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor);
CoglTexturePixmapX11 *pixmap;
self->received_damage = TRUE;
@@ -215,8 +216,12 @@ meta_surface_actor_x11_process_damage (MetaSurfaceActor *actor,
if (!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 here */
if (!meta_multi_texture_is_simple (self->texture))
return;
pixmap = COGL_TEXTURE_PIXMAP_X11 (meta_multi_texture_get_subtexture (self->texture, 0));
cogl_texture_pixmap_x11_update_area (pixmap, x, y, width, height);
}
static void

View File

@@ -58,8 +58,8 @@ typedef struct
struct _MetaTextureTower
{
int n_levels;
CoglTexture *textures[MAX_TEXTURE_LEVELS];
CoglOffscreen *fbos[MAX_TEXTURE_LEVELS];
MetaMultiTexture *textures[MAX_TEXTURE_LEVELS];
GList *fbos[MAX_TEXTURE_LEVELS];
Box invalid[MAX_TEXTURE_LEVELS];
CoglPipeline *pipeline_template;
};
@@ -113,7 +113,7 @@ meta_texture_tower_free (MetaTextureTower *tower)
*/
void
meta_texture_tower_set_base_texture (MetaTextureTower *tower,
CoglTexture *texture)
MetaMultiTexture *texture)
{
int i;
@@ -126,20 +126,12 @@ meta_texture_tower_set_base_texture (MetaTextureTower *tower,
{
for (i = 1; i < tower->n_levels; i++)
{
if (tower->textures[i] != NULL)
{
cogl_object_unref (tower->textures[i]);
tower->textures[i] = NULL;
}
if (tower->fbos[i] != NULL)
{
cogl_object_unref (tower->fbos[i]);
tower->fbos[i] = NULL;
}
g_clear_object (&tower->textures[i]);
g_list_free_full (tower->fbos[i], cogl_object_unref);
tower->fbos[i] = NULL;
}
cogl_object_unref (tower->textures[0]);
g_object_unref (tower->textures[0]);
}
tower->textures[0] = texture;
@@ -148,10 +140,10 @@ meta_texture_tower_set_base_texture (MetaTextureTower *tower,
{
int width, height;
cogl_object_ref (tower->textures[0]);
g_object_ref (tower->textures[0]);
width = cogl_texture_get_width (tower->textures[0]);
height = cogl_texture_get_height (tower->textures[0]);
width = meta_multi_texture_get_width (tower->textures[0]);
height = meta_multi_texture_get_height (tower->textures[0]);
tower->n_levels = 1 + MAX ((int)(M_LOG2E * log (width)), (int)(M_LOG2E * log (height)));
tower->n_levels = MIN(tower->n_levels, MAX_TEXTURE_LEVELS);
@@ -192,8 +184,8 @@ meta_texture_tower_update_area (MetaTextureTower *tower,
if (tower->textures[0] == NULL)
return;
texture_width = cogl_texture_get_width (tower->textures[0]);
texture_height = cogl_texture_get_height (tower->textures[0]);
texture_width = meta_multi_texture_get_width (tower->textures[0]);
texture_height = meta_multi_texture_get_height (tower->textures[0]);
invalid.x1 = x;
invalid.y1 = y;
@@ -355,9 +347,28 @@ texture_tower_create_texture (MetaTextureTower *tower,
int width,
int height)
{
tower->textures[level] = cogl_texture_new_with_size (width, height,
COGL_TEXTURE_NO_AUTO_MIPMAP,
TEXTURE_FORMAT);
MetaMultiTextureFormat format;
guint i, n_subtextures;
GPtrArray *subtextures;
CoglTexture **textures;
format = meta_multi_texture_get_format (tower->textures[0]);
n_subtextures = meta_multi_texture_format_get_n_planes (format);
subtextures = g_ptr_array_new_full (n_subtextures, g_object_unref);
for (i = 0; i < n_subtextures; i++)
{
CoglTexture *texture;
texture = cogl_texture_new_with_size (width, height,
COGL_TEXTURE_NO_AUTO_MIPMAP,
TEXTURE_FORMAT);
g_ptr_array_add (subtextures, texture);
}
textures = (CoglTexture **) g_ptr_array_free (subtextures, FALSE);
tower->textures[level] = meta_multi_texture_new (format,
textures,
n_subtextures);
tower->invalid[level].x1 = 0;
tower->invalid[level].y1 = 0;
@@ -369,51 +380,69 @@ static void
texture_tower_revalidate (MetaTextureTower *tower,
int level)
{
CoglTexture *source_texture = tower->textures[level - 1];
int source_texture_width = cogl_texture_get_width (source_texture);
int source_texture_height = cogl_texture_get_height (source_texture);
CoglTexture *dest_texture = tower->textures[level];
int dest_texture_width = cogl_texture_get_width (dest_texture);
int dest_texture_height = cogl_texture_get_height (dest_texture);
MetaMultiTexture *src_tex = tower->textures[level - 1];
int src_width = meta_multi_texture_get_width (src_tex);
int src_height = meta_multi_texture_get_height (src_tex);
guint src_n_subtextures = meta_multi_texture_get_n_subtextures (src_tex);
MetaMultiTexture *dest_tex = tower->textures[level];
int dest_width = meta_multi_texture_get_width (dest_tex);
int dest_height = meta_multi_texture_get_height (dest_tex);
Box *invalid = &tower->invalid[level];
CoglFramebuffer *fb;
GError *catch_error = NULL;
CoglPipeline *pipeline;
guint i;
if (tower->fbos[level] == NULL)
tower->fbos[level] = cogl_offscreen_new_with_texture (dest_texture);
fb = COGL_FRAMEBUFFER (tower->fbos[level]);
if (!cogl_framebuffer_allocate (fb, &catch_error))
/* FIXME: cogl_offscreen_texture_new_with_texture doesn't work for
* multi-plane textures, so we have to make an FBO for each layer */
for (i = 0; i < src_n_subtextures; i++)
{
g_error_free (catch_error);
return;
Box *invalid = &tower->invalid[level];
CoglTexture *src_subtexture, *dest_subtexture;
CoglFramebuffer *fb;
GError *catch_error = NULL;
CoglPipeline *pipeline;
src_subtexture = meta_multi_texture_get_subtexture (src_tex, i);
dest_subtexture = meta_multi_texture_get_subtexture (dest_tex, i);
if (g_list_nth (tower->fbos[level], i) != NULL)
{
fb = COGL_FRAMEBUFFER (g_list_nth (tower->fbos[level], i)->data);
}
else
{
fb = COGL_FRAMEBUFFER (cogl_offscreen_new_with_texture (dest_subtexture));
tower->fbos[level] = g_list_append (tower->fbos[level], fb);
}
if (!cogl_framebuffer_allocate (fb, &catch_error))
{
g_error_free (catch_error);
return;
}
cogl_framebuffer_orthographic (fb, 0, 0, dest_width, dest_height, -1., 1.);
if (!tower->pipeline_template)
{
CoglContext *ctx =
clutter_backend_get_cogl_context (clutter_get_default_backend ());
tower->pipeline_template = cogl_pipeline_new (ctx);
cogl_pipeline_set_blend (tower->pipeline_template, "RGBA = ADD (SRC_COLOR, 0)", NULL);
}
pipeline = cogl_pipeline_copy (tower->pipeline_template);
cogl_pipeline_set_layer_texture (pipeline, 0, src_subtexture);
cogl_framebuffer_draw_textured_rectangle (fb, pipeline,
invalid->x1, invalid->y1,
invalid->x2, invalid->y2,
(2. * invalid->x1) / src_width,
(2. * invalid->y1) / src_height,
(2. * invalid->x2) / src_width,
(2. * invalid->y2) / src_height);
cogl_object_unref (pipeline);
}
cogl_framebuffer_orthographic (fb, 0, 0, dest_texture_width, dest_texture_height, -1., 1.);
if (!tower->pipeline_template)
{
CoglContext *ctx =
clutter_backend_get_cogl_context (clutter_get_default_backend ());
tower->pipeline_template = cogl_pipeline_new (ctx);
cogl_pipeline_set_blend (tower->pipeline_template, "RGBA = ADD (SRC_COLOR, 0)", NULL);
}
pipeline = cogl_pipeline_copy (tower->pipeline_template);
cogl_pipeline_set_layer_texture (pipeline, 0, tower->textures[level - 1]);
cogl_framebuffer_draw_textured_rectangle (fb, pipeline,
invalid->x1, invalid->y1,
invalid->x2, invalid->y2,
(2. * invalid->x1) / source_texture_width,
(2. * invalid->y1) / source_texture_height,
(2. * invalid->x2) / source_texture_width,
(2. * invalid->y2) / source_texture_height);
cogl_object_unref (pipeline);
tower->invalid[level].x1 = tower->invalid[level].x2 = 0;
tower->invalid[level].y1 = tower->invalid[level].y2 = 0;
}
@@ -432,8 +461,8 @@ texture_tower_revalidate (MetaTextureTower *tower,
* Return value: the COGL texture handle to use for painting, or
* %NULL if no base texture has yet been set.
*/
CoglTexture *
meta_texture_tower_get_paint_texture (MetaTextureTower *tower,
MetaMultiTexture *
meta_texture_tower_get_paint_texture (MetaTextureTower *tower,
ClutterPaintContext *paint_context)
{
int texture_width, texture_height;
@@ -444,8 +473,8 @@ meta_texture_tower_get_paint_texture (MetaTextureTower *tower,
if (tower->textures[0] == NULL)
return NULL;
texture_width = cogl_texture_get_width (tower->textures[0]);
texture_height = cogl_texture_get_height (tower->textures[0]);
texture_width = meta_multi_texture_get_width (tower->textures[0]);
texture_height = meta_multi_texture_get_height (tower->textures[0]);
level = get_paint_level (paint_context, texture_width, texture_height);
if (level < 0) /* singular paint matrix, scaled to nothing */

View File

@@ -24,6 +24,7 @@
#define __META_TEXTURE_TOWER_H__
#include "clutter/clutter.h"
#include <meta/meta-multi-texture.h>
G_BEGIN_DECLS
@@ -54,13 +55,13 @@ typedef struct _MetaTextureTower MetaTextureTower;
MetaTextureTower *meta_texture_tower_new (void);
void meta_texture_tower_free (MetaTextureTower *tower);
void meta_texture_tower_set_base_texture (MetaTextureTower *tower,
CoglTexture *texture);
MetaMultiTexture *texture);
void meta_texture_tower_update_area (MetaTextureTower *tower,
int x,
int y,
int width,
int height);
CoglTexture *meta_texture_tower_get_paint_texture (MetaTextureTower *tower,
MetaMultiTexture *meta_texture_tower_get_paint_texture (MetaTextureTower *tower,
ClutterPaintContext *paint_context);
G_END_DECLS

View File

@@ -302,6 +302,8 @@ mutter_sources = [
'compositor/meta-feedback-actor-private.h',
'compositor/meta-module.c',
'compositor/meta-module.h',
'compositor/meta-multi-texture.c',
'compositor/meta-multi-texture-format.c',
'compositor/meta-plugin.c',
'compositor/meta-plugin-manager.c',
'compositor/meta-plugin-manager.h',

View File

@@ -20,6 +20,8 @@ mutter_public_headers = [
'meta-inhibit-shortcuts-dialog.h',
'meta-launch-context.h',
'meta-monitor-manager.h',
'meta-multi-texture.h',
'meta-multi-texture-format.h',
'meta-plugin.h',
'meta-remote-access-controller.h',
'meta-selection.h',

View File

@@ -0,0 +1,138 @@
/*
* Authored By Niels De Graef <niels.degraef@barco.com>
*
* Copyright (C) 2018 Barco NV
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef __META_MULTI_TEXTURE_FORMAT_H__
#define __META_MULTI_TEXTURE_FORMAT_H__
#include <glib.h>
#include <cogl/cogl.h>
#include <meta/common.h>
G_BEGIN_DECLS
/**
* MetaMultiTextureFormat:
* @META_MULTI_TEXTURE_FORMAT_FORMAT_SIMPLE: Any format supported by Cogl (see #CoglPixelFormat)
* @META_MULTI_TEXTURE_FORMAT_FORMAT_YUYV: YUYV, 32 bits, 16 bpc (Y), 8 bpc (U & V)
* @META_MULTI_TEXTURE_FORMAT_FORMAT_YVYU: YVYU, 32 bits, 16 bpc (Y), 8 bpc (V & U)
* @META_MULTI_TEXTURE_FORMAT_FORMAT_UYVY: UYVY, 32 bits, 16 bpc (Y), 8 bpc (V & U)
* @META_MULTI_TEXTURE_FORMAT_FORMAT_VYUY: VYUV, 32 bits, 16 bpc (Y), 8 bpc (V & U)
* @META_MULTI_TEXTURE_FORMAT_FORMAT_AYUV: AYUV, 32 bits, 8 bpc
* @META_MULTI_TEXTURE_FORMAT_FORMAT_XRGB8888_A8: 2 planes: 1 RGB-plane (64-bit), 1 alpha-plane
* @META_MULTI_TEXTURE_FORMAT_FORMAT_XBGR8888_A8: 2 planes: 1 BGR-plane (64-bit), 1 alpha-plane
* @META_MULTI_TEXTURE_FORMAT_FORMAT_RGBX8888_A8: 2 planes: 1 RGB-plane (64-bit), 1 alpha-plane
* @META_MULTI_TEXTURE_FORMAT_FORMAT_BGRX8888_A8: 2 planes: 1 BGR-plane (64-bit), 1 alpha-plane
* @META_MULTI_TEXTURE_FORMAT_FORMAT_RGB888_A8: 2 planes: 1 RGB-plane (32-bit), 1 alpha-plane
* @META_MULTI_TEXTURE_FORMAT_FORMAT_BGR888_A8: 2 planes: 1 BGR-plane (32-bit), 1 alpha-plane
* @META_MULTI_TEXTURE_FORMAT_FORMAT_RGB565_A8: 2 planes: 1 RGB-plane (16-bit), 1 alpha-plane
* @META_MULTI_TEXTURE_FORMAT_FORMAT_BGR565_A8: 2 planes: 1 BGR-plane (16-bit), 1 alpha-plane
* @META_MULTI_TEXTURE_FORMAT_FORMAT_NV12: 2 planes: 1 Y-plane, 1 UV-plane (2x2 subsampled)
* @META_MULTI_TEXTURE_FORMAT_FORMAT_NV21: 2 planes: 1 Y-plane, 1 VU-plane (2x2 subsampled)
* @META_MULTI_TEXTURE_FORMAT_FORMAT_NV16: 2 planes: 1 Y-plane, 1 UV-plane (2x1 subsampled)
* @META_MULTI_TEXTURE_FORMAT_FORMAT_NV61: 2 planes: 1 Y-plane, 1 VU-plane (2x1 subsampled)
* @META_MULTI_TEXTURE_FORMAT_FORMAT_NV24: 2 planes: 1 Y-plane, 1 UV-plane
* @META_MULTI_TEXTURE_FORMAT_FORMAT_NV42: 2 planes: 1 Y-plane, 1 VU-plane
* @META_MULTI_TEXTURE_FORMAT_FORMAT_YUV410: 3 planes: 1 Y-plane, 1 U-plane (4x4 subsampled), 1 V-plane (4x4 subsampled)
* @META_MULTI_TEXTURE_FORMAT_FORMAT_YVU410: 3 planes: 1 Y-plane, 1 V-plane (4x4 subsampled), 1 U-plane (4x4 subsampled)
* @META_MULTI_TEXTURE_FORMAT_FORMAT_YUV411: 3 planes: 1 Y-plane, 1 U-plane (4x1 subsampled), 1 V-plane (4x1 subsampled)
* @META_MULTI_TEXTURE_FORMAT_FORMAT_YVU411: 3 planes: 1 Y-plane, 1 V-plane (4x1 subsampled), 1 U-plane (4x1 subsampled)
* @META_MULTI_TEXTURE_FORMAT_FORMAT_YUV420: 3 planes: 1 Y-plane, 1 U-plane (2x2 subsampled), 1 V-plane (2x2 subsampled)
* @META_MULTI_TEXTURE_FORMAT_FORMAT_YVU420: 3 planes: 1 Y-plane, 1 V-plane (2x2 subsampled), 1 U-plane (2x2 subsampled)
* @META_MULTI_TEXTURE_FORMAT_FORMAT_YUV422: 3 planes: 1 Y-plane, 1 U-plane (2x1 subsampled), 1 V-plane (2x1 subsampled)
* @META_MULTI_TEXTURE_FORMAT_FORMAT_YVU422: 3 planes: 1 Y-plane, 1 V-plane (2x1 subsampled), 1 U-plane (2x1 subsampled)
* @META_MULTI_TEXTURE_FORMAT_FORMAT_YUV444: 3 planes: 1 Y-plane, 1 U-plane, 1 V-plane
* @META_MULTI_TEXTURE_FORMAT_FORMAT_YVU444: 3 planes: 1 Y-plane, 1 V-plane, 1 U-plane
*
* XXX write docs
*/
typedef enum _MetaMultiTextureFormat
{
META_MULTI_TEXTURE_FORMAT_SIMPLE,
/* The following list is somewhat synced with Linux's <drm_fourcc.h> */
/* Packed YUV */
META_MULTI_TEXTURE_FORMAT_YUYV,
META_MULTI_TEXTURE_FORMAT_YVYU,
META_MULTI_TEXTURE_FORMAT_UYVY,
META_MULTI_TEXTURE_FORMAT_VYUY,
META_MULTI_TEXTURE_FORMAT_AYUV,
/* 2 plane RGB + A */
META_MULTI_TEXTURE_FORMAT_XRGB8888_A8,
META_MULTI_TEXTURE_FORMAT_XBGR8888_A8,
META_MULTI_TEXTURE_FORMAT_RGBX8888_A8,
META_MULTI_TEXTURE_FORMAT_BGRX8888_A8,
META_MULTI_TEXTURE_FORMAT_RGB888_A8,
META_MULTI_TEXTURE_FORMAT_BGR888_A8,
META_MULTI_TEXTURE_FORMAT_RGB565_A8,
META_MULTI_TEXTURE_FORMAT_BGR565_A8,
/* 2 plane YUV */
META_MULTI_TEXTURE_FORMAT_NV12,
META_MULTI_TEXTURE_FORMAT_NV21,
META_MULTI_TEXTURE_FORMAT_NV16,
META_MULTI_TEXTURE_FORMAT_NV61,
META_MULTI_TEXTURE_FORMAT_NV24,
META_MULTI_TEXTURE_FORMAT_NV42,
/* 3 plane YUV */
META_MULTI_TEXTURE_FORMAT_YUV410,
META_MULTI_TEXTURE_FORMAT_YVU410,
META_MULTI_TEXTURE_FORMAT_YUV411,
META_MULTI_TEXTURE_FORMAT_YVU411,
META_MULTI_TEXTURE_FORMAT_YUV420,
META_MULTI_TEXTURE_FORMAT_YVU420,
META_MULTI_TEXTURE_FORMAT_YUV422,
META_MULTI_TEXTURE_FORMAT_YVU422,
META_MULTI_TEXTURE_FORMAT_YUV444,
META_MULTI_TEXTURE_FORMAT_YVU444
} MetaMultiTextureFormat;
META_EXPORT
void meta_multi_texture_format_get_bytes_per_pixel (MetaMultiTextureFormat format,
uint8_t *bpp_out);
META_EXPORT
int meta_multi_texture_format_get_n_planes (MetaMultiTextureFormat format);
META_EXPORT
void meta_multi_texture_format_get_subsampling_factors (MetaMultiTextureFormat format,
uint8_t *horizontal_factors,
uint8_t *vertical_factors);
META_EXPORT
void meta_multi_texture_format_get_subformats (MetaMultiTextureFormat format,
CoglPixelFormat *formats_out);
META_EXPORT
gboolean meta_multi_texture_format_needs_shaders (MetaMultiTextureFormat format);
META_EXPORT
gboolean meta_multi_texture_format_get_snippets (MetaMultiTextureFormat format,
CoglSnippet **vertex_snippet,
CoglSnippet **fragment_snippet,
CoglSnippet **layer_snippet);
G_END_DECLS
#endif

View File

@@ -0,0 +1,72 @@
/*
* Authored By Niels De Graef <niels.degraef@barco.com>
*
* Copyright (C) 2018 Barco NV
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef __META_MULTI_TEXTURE_H__
#define __META_MULTI_TEXTURE_H__
#include <glib-object.h>
#include <cogl/cogl.h>
#include <meta/common.h>
#include "meta/meta-multi-texture-format.h"
G_BEGIN_DECLS
#define META_TYPE_MULTI_TEXTURE (meta_multi_texture_get_type ())
META_EXPORT
G_DECLARE_FINAL_TYPE (MetaMultiTexture, meta_multi_texture,
META, MULTI_TEXTURE,
GObject)
META_EXPORT
MetaMultiTexture * meta_multi_texture_new (MetaMultiTextureFormat format,
CoglTexture **subtextures,
guint n_subtextures);
META_EXPORT
MetaMultiTexture * meta_multi_texture_new_simple (CoglTexture *subtexture);
META_EXPORT
MetaMultiTextureFormat meta_multi_texture_get_format (MetaMultiTexture *self);
META_EXPORT
gboolean meta_multi_texture_is_simple (MetaMultiTexture *self);
META_EXPORT
guint meta_multi_texture_get_n_subtextures (MetaMultiTexture *self);
META_EXPORT
CoglTexture * meta_multi_texture_get_subtexture (MetaMultiTexture *self,
guint index);
META_EXPORT
int meta_multi_texture_get_width (MetaMultiTexture *self);
META_EXPORT
int meta_multi_texture_get_height (MetaMultiTexture *self);
META_EXPORT
char * meta_multi_texture_to_string (MetaMultiTexture *self);
G_END_DECLS
#endif

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

@@ -155,7 +155,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;
@@ -182,46 +182,50 @@ meta_wayland_buffer_realize (MetaWaylandBuffer *buffer)
}
static void
shm_buffer_get_cogl_pixel_format (struct wl_shm_buffer *shm_buffer,
CoglPixelFormat *format_out,
CoglTextureComponents *components_out)
shm_buffer_get_format (struct wl_shm_buffer *shm_buffer,
MetaMultiTextureFormat *multi_format_out,
CoglPixelFormat *cogl_format_out,
CoglTextureComponents *components_out)
{
CoglPixelFormat format;
MetaMultiTextureFormat multi_format = META_MULTI_TEXTURE_FORMAT_SIMPLE;
CoglPixelFormat cogl_format = COGL_PIXEL_FORMAT_ANY;
CoglTextureComponents components = COGL_TEXTURE_COMPONENTS_RGBA;
switch (wl_shm_buffer_get_format (shm_buffer))
{
#if G_BYTE_ORDER == G_BIG_ENDIAN
case WL_SHM_FORMAT_ARGB8888:
format = COGL_PIXEL_FORMAT_ARGB_8888_PRE;
cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE;
break;
case WL_SHM_FORMAT_XRGB8888:
format = COGL_PIXEL_FORMAT_ARGB_8888;
cogl_format = COGL_PIXEL_FORMAT_ARGB_8888;
components = COGL_TEXTURE_COMPONENTS_RGB;
break;
#elif G_BYTE_ORDER == G_LITTLE_ENDIAN
case WL_SHM_FORMAT_ARGB8888:
format = COGL_PIXEL_FORMAT_BGRA_8888_PRE;
cogl_format = COGL_PIXEL_FORMAT_BGRA_8888_PRE;
break;
case WL_SHM_FORMAT_XRGB8888:
format = COGL_PIXEL_FORMAT_BGRA_8888;
cogl_format = COGL_PIXEL_FORMAT_BGRA_8888;
components = COGL_TEXTURE_COMPONENTS_RGB;
break;
#endif
default:
g_warn_if_reached ();
format = COGL_PIXEL_FORMAT_ARGB_8888;
cogl_format = COGL_PIXEL_FORMAT_ARGB_8888;
}
if (format_out)
*format_out = format;
if (multi_format_out)
*multi_format_out = multi_format;
if (cogl_format_out)
*cogl_format_out = cogl_format;
if (components_out)
*components_out = components;
}
static gboolean
shm_buffer_attach (MetaWaylandBuffer *buffer,
CoglTexture **texture,
MetaMultiTexture **texture,
GError **error)
{
MetaBackend *backend = meta_get_backend ();
@@ -229,43 +233,51 @@ shm_buffer_attach (MetaWaylandBuffer *buffer,
CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
struct wl_shm_buffer *shm_buffer;
int stride, width, height;
CoglPixelFormat format;
MetaMultiTextureFormat multi_format;
CoglPixelFormat cogl_format;
CoglTextureComponents components;
CoglBitmap *bitmap;
CoglTexture *new_texture;
CoglTexture *new_cogl_tex;
shm_buffer = wl_shm_buffer_get (buffer->resource);
stride = wl_shm_buffer_get_stride (shm_buffer);
width = wl_shm_buffer_get_width (shm_buffer);
height = wl_shm_buffer_get_height (shm_buffer);
shm_buffer_get_cogl_pixel_format (shm_buffer, &format, &components);
shm_buffer_get_format (shm_buffer, &multi_format, &cogl_format, &components);
/* We only support "simple" textures for now */
g_return_val_if_fail (multi_format == META_MULTI_TEXTURE_FORMAT_SIMPLE, FALSE);
if (*texture &&
cogl_texture_get_width (*texture) == width &&
cogl_texture_get_height (*texture) == height &&
cogl_texture_get_components (*texture) == components &&
_cogl_texture_get_format (*texture) == format)
meta_multi_texture_get_width (*texture) == width &&
meta_multi_texture_get_height (*texture) == height &&
meta_multi_texture_get_format (*texture) == multi_format)
{
buffer->is_y_inverted = TRUE;
return TRUE;
CoglTexture *cogl_texture = meta_multi_texture_get_subtexture (*texture, 0);
if (cogl_texture_get_components (cogl_texture) == components &&
_cogl_texture_get_format (cogl_texture) == cogl_format)
{
buffer->is_y_inverted = TRUE;
return TRUE;
}
}
cogl_clear_object (texture);
g_clear_object (texture);
wl_shm_buffer_begin_access (shm_buffer);
bitmap = cogl_bitmap_new_for_data (cogl_context,
width, height,
format,
cogl_format,
stride,
wl_shm_buffer_get_data (shm_buffer));
new_texture = COGL_TEXTURE (cogl_texture_2d_new_from_bitmap (bitmap));
cogl_texture_set_components (new_texture, components);
new_cogl_tex = COGL_TEXTURE (cogl_texture_2d_new_from_bitmap (bitmap));
cogl_texture_set_components (new_cogl_tex, components);
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;
@@ -275,11 +287,11 @@ 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);
cogl_texture_set_components (new_texture, components);
new_cogl_tex = COGL_TEXTURE (texture_sliced);
cogl_texture_set_components (new_cogl_tex, components);
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);
}
}
@@ -287,10 +299,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;
@@ -298,7 +310,7 @@ shm_buffer_attach (MetaWaylandBuffer *buffer,
static gboolean
egl_image_buffer_attach (MetaWaylandBuffer *buffer,
CoglTexture **texture,
MetaMultiTexture **texture,
GError **error)
{
MetaBackend *backend = meta_get_backend ();
@@ -307,15 +319,15 @@ 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);
int format, width, height, y_inverted;
CoglPixelFormat cogl_format;
EGLImageKHR egl_image;
CoglEglImageFlags flags;
CoglTexture2D *texture_2d;
MetaMultiTextureFormat multi_format = META_MULTI_TEXTURE_FORMAT_SIMPLE;
CoglPixelFormat cogl_format = COGL_PIXEL_FORMAT_ANY;
guint i, n_subtextures;
GPtrArray *subtextures;
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;
}
@@ -339,6 +351,7 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
NULL))
y_inverted = EGL_TRUE;
/* Query the color format */
switch (format)
{
case EGL_TEXTURE_RGB:
@@ -347,6 +360,16 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
case EGL_TEXTURE_RGBA:
cogl_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE;
break;
case EGL_TEXTURE_Y_UV_WL:
/* Technically it can be anything with a separate Y and UV subtexture
* but since this is only used for shaders later, it's ok */
multi_format = META_MULTI_TEXTURE_FORMAT_NV12;
break;
case EGL_TEXTURE_Y_U_V_WL:
/* Technically it can be anything with a separate Y and UV subtexture
* but since this is only used for shaders later, it's ok */
multi_format = META_MULTI_TEXTURE_FORMAT_YUV444;
break;
default:
g_set_error (error, G_IO_ERROR,
G_IO_ERROR_FAILED,
@@ -354,41 +377,70 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
return FALSE;
}
/* The WL_bind_wayland_display spec states that EGL_NO_CONTEXT is to be used
* in conjunction with the EGL_WAYLAND_BUFFER_WL target. */
egl_image = meta_egl_create_image (egl, egl_display, EGL_NO_CONTEXT,
EGL_WAYLAND_BUFFER_WL, buffer->resource,
NULL,
error);
if (egl_image == EGL_NO_IMAGE_KHR)
return FALSE;
/* Each EGLImage is a subtexture in the final texture */
n_subtextures = meta_multi_texture_format_get_n_planes (multi_format);
subtextures = g_ptr_array_new_full (n_subtextures, cogl_object_unref);
flags = COGL_EGL_IMAGE_FLAG_NONE;
texture_2d = cogl_egl_texture_2d_new_from_image (cogl_context,
width, height,
cogl_format,
egl_image,
flags,
error);
g_warning ("Got EGL with format %u", multi_format);
meta_egl_destroy_image (egl, egl_display, egl_image, NULL);
for (i = 0; i < n_subtextures; i++)
{
EGLint egl_attribs[3];
EGLImageKHR egl_img;
CoglEglImageFlags flags;
CoglTexture2D *texture_2d;
if (!texture_2d)
return FALSE;
/* Specify that we want the i'th subtexture */
egl_attribs[0] = EGL_WAYLAND_PLANE_WL;
egl_attribs[1] = i;
egl_attribs[2] = EGL_NONE;
buffer->egl_image.texture = COGL_TEXTURE (texture_2d);
/* The WL_bind_wayland_display spec states that EGL_NO_CONTEXT is to be
* used in conjunction with the EGL_WAYLAND_BUFFER_WL target. */
egl_img = meta_egl_create_image (egl, egl_display, EGL_NO_CONTEXT,
EGL_WAYLAND_BUFFER_WL, buffer->resource,
egl_attribs,
error);
if (G_UNLIKELY (egl_img == EGL_NO_IMAGE_KHR))
goto on_error;
flags = COGL_EGL_IMAGE_FLAG_NONE;
texture_2d = cogl_egl_texture_2d_new_from_image (cogl_context,
width, height,
cogl_format,
egl_img,
flags,
error);
meta_egl_destroy_image (egl, egl_display, egl_img, NULL);
if (G_UNLIKELY (!texture_2d))
goto on_error;
g_ptr_array_add (subtextures, COGL_TEXTURE (texture_2d));
}
buffer->egl_image.texture =
meta_multi_texture_new (multi_format,
(CoglTexture**) g_ptr_array_free (subtextures, FALSE),
n_subtextures);
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;
on_error:
g_ptr_array_free (subtextures, TRUE);
return FALSE;
}
#ifdef HAVE_WAYLAND_EGLSTREAM
static gboolean
egl_stream_buffer_attach (MetaWaylandBuffer *buffer,
CoglTexture **texture,
MetaMultiTexture **texture,
GError **error)
{
MetaWaylandEglStream *stream = buffer->egl_stream.stream;
@@ -398,8 +450,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;
}
@@ -408,8 +460,8 @@ egl_stream_buffer_attach (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
@@ -426,7 +478,7 @@ egl_stream_buffer_attach (MetaWaylandBuffer *buffer,
*/
gboolean
meta_wayland_buffer_attach (MetaWaylandBuffer *buffer,
CoglTexture **texture,
MetaMultiTexture **texture,
GError **error)
{
g_return_val_if_fail (buffer->resource, FALSE);
@@ -493,21 +545,24 @@ 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)
{
struct wl_shm_buffer *shm_buffer;
int i, n_rectangles;
gboolean set_texture_failed = FALSE;
CoglPixelFormat format;
MetaMultiTextureFormat multi_format;
CoglPixelFormat cogl_format;
CoglTexture *cogl_texture;
n_rectangles = cairo_region_num_rectangles (region);
shm_buffer = wl_shm_buffer_get (buffer->resource);
shm_buffer_get_cogl_pixel_format (shm_buffer, &format, NULL);
g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, FALSE);
shm_buffer_get_format (shm_buffer, &multi_format, &cogl_format, NULL);
g_return_val_if_fail (multi_format == META_MULTI_TEXTURE_FORMAT_SIMPLE, FALSE);
cogl_texture = meta_multi_texture_get_subtexture (texture, 0);
wl_shm_buffer_begin_access (shm_buffer);
@@ -518,12 +573,12 @@ process_shm_buffer_damage (MetaWaylandBuffer *buffer,
cairo_rectangle_int_t rect;
int bpp;
bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0);
bpp = cogl_pixel_format_get_bytes_per_pixel (cogl_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,
cogl_format,
stride,
data + rect.x * bpp + rect.y * stride,
rect.x, rect.y,
@@ -542,7 +597,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;
@@ -582,12 +637,12 @@ meta_wayland_buffer_finalize (GObject *object)
{
MetaWaylandBuffer *buffer = META_WAYLAND_BUFFER (object);
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_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"
@@ -56,19 +57,19 @@ 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;
};
@@ -81,12 +82,12 @@ 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);
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);
#endif /* META_WAYLAND_BUFFER_H */

View File

@@ -58,16 +58,20 @@ 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)
{
/* We don't support complex textures for cursors */
g_return_if_fail (meta_multi_texture_is_simple (texture));
meta_cursor_sprite_set_texture (cursor_sprite,
texture,
meta_multi_texture_get_subtexture (texture, 0),
priv->hot_x * surface->scale,
priv->hot_y * surface->scale);
}

View File

@@ -87,10 +87,12 @@ meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer *buffer,
MetaWaylandDmaBufBuffer *dma_buf = buffer->dma_buf.dma_buf;
uint32_t n_planes;
uint64_t modifiers[META_WAYLAND_DMA_BUF_MAX_FDS];
CoglPixelFormat cogl_format;
MetaMultiTextureFormat multi_format = META_MULTI_TEXTURE_FORMAT_SIMPLE;
CoglPixelFormat subformats[META_WAYLAND_DMA_BUF_MAX_FDS] = { COGL_PIXEL_FORMAT_ANY, };
EGLImageKHR egl_image;
CoglEglImageFlags flags;
CoglTexture2D *texture;
CoglTexture2D *cogl_texture;
GPtrArray *planes;
if (buffer->dma_buf.texture)
return TRUE;
@@ -105,16 +107,55 @@ meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer *buffer,
* and access the buffer memory at all.
*/
case DRM_FORMAT_XRGB8888:
cogl_format = COGL_PIXEL_FORMAT_RGB_888;
subformats[0] = COGL_PIXEL_FORMAT_RGB_888;
break;
case DRM_FORMAT_ARGB8888:
cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE;
subformats[0] = COGL_PIXEL_FORMAT_ARGB_8888_PRE;
break;
case DRM_FORMAT_ARGB2101010:
cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010_PRE;
subformats[0] = COGL_PIXEL_FORMAT_ARGB_2101010_PRE;
break;
case DRM_FORMAT_RGB565:
cogl_format = COGL_PIXEL_FORMAT_RGB_565;
subformats[0] = COGL_PIXEL_FORMAT_RGB_565;
break;
case DRM_FORMAT_YUYV:
multi_format = META_MULTI_TEXTURE_FORMAT_YUYV;
break;
case DRM_FORMAT_NV12:
multi_format = META_MULTI_TEXTURE_FORMAT_NV12;
break;
case DRM_FORMAT_NV21:
multi_format = META_MULTI_TEXTURE_FORMAT_NV21;
break;
case DRM_FORMAT_YUV410:
multi_format = META_MULTI_TEXTURE_FORMAT_YUV410;
break;
case DRM_FORMAT_YVU410:
multi_format = META_MULTI_TEXTURE_FORMAT_YVU410;
break;
case DRM_FORMAT_YUV411:
multi_format = META_MULTI_TEXTURE_FORMAT_YUV411;
break;
case DRM_FORMAT_YVU411:
multi_format = META_MULTI_TEXTURE_FORMAT_YVU411;
break;
case DRM_FORMAT_YUV420:
multi_format = META_MULTI_TEXTURE_FORMAT_YUV420;
break;
case DRM_FORMAT_YVU420:
multi_format = META_MULTI_TEXTURE_FORMAT_YVU420;
break;
case DRM_FORMAT_YUV422:
multi_format = META_MULTI_TEXTURE_FORMAT_YUV422;
break;
case DRM_FORMAT_YVU422:
multi_format = META_MULTI_TEXTURE_FORMAT_YVU422;
break;
case DRM_FORMAT_YUV444:
multi_format = META_MULTI_TEXTURE_FORMAT_YUV444;
break;
case DRM_FORMAT_YVU444:
multi_format = META_MULTI_TEXTURE_FORMAT_YVU444;
break;
default:
g_set_error (error, G_IO_ERROR,
@@ -123,6 +164,9 @@ meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer *buffer,
return FALSE;
}
if (multi_format != META_MULTI_TEXTURE_FORMAT_SIMPLE)
meta_multi_texture_format_get_subformats (multi_format, subformats);
for (n_planes = 0; n_planes < META_WAYLAND_DMA_BUF_MAX_FDS; n_planes++)
{
if (dma_buf->fds[n_planes] < 0)
@@ -131,6 +175,8 @@ meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer *buffer,
modifiers[n_planes] = dma_buf->drm_modifier;
}
planes = g_ptr_array_new_full (n_planes, cogl_object_unref);
egl_image = meta_egl_create_dmabuf_image (egl,
egl_display,
dma_buf->width,
@@ -143,23 +189,36 @@ meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer *buffer,
modifiers,
error);
if (egl_image == EGL_NO_IMAGE_KHR)
return FALSE;
{
g_debug ("Couldn't create EGLImage from DMA-buf: %s", (*error)->message);
return FALSE;
}
/* FIXME: at this point, we might want to try importing each plane separately */
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,
subformats[0],
egl_image,
flags,
error);
meta_egl_destroy_image (egl, egl_display, egl_image, NULL);
if (!texture)
return FALSE;
if (cogl_texture == NULL)
{
g_debug ("Couldn't upload DMA-buf EGLImage: %s", *error? (*error)->message : "");
return FALSE;
}
buffer->dma_buf.texture = COGL_TEXTURE (texture);
g_ptr_array_add (planes, COGL_TEXTURE (cogl_texture));
buffer->dma_buf.texture =
meta_multi_texture_new (multi_format,
(CoglTexture**) g_ptr_array_free (planes, FALSE),
n_planes);
buffer->is_y_inverted = dma_buf->is_y_inverted;
return TRUE;
@@ -167,14 +226,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;
}
@@ -530,6 +589,7 @@ dma_buf_bind (struct wl_client *client,
send_modifiers (resource, DRM_FORMAT_XRGB8888);
send_modifiers (resource, DRM_FORMAT_ARGB2101010);
send_modifiers (resource, DRM_FORMAT_RGB565);
send_modifiers (resource, DRM_FORMAT_NV12);
}
/**

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 ())
@@ -43,7 +44,7 @@ gboolean meta_wayland_dma_buf_init (MetaWaylandCompositor *compositor);
gboolean
meta_wayland_dma_buf_buffer_attach (MetaWaylandBuffer *buffer,
CoglTexture **texture,
MetaMultiTexture **texture,
GError **error);
MetaWaylandDmaBufBuffer *

View File

@@ -241,7 +241,7 @@ get_buffer_width (MetaWaylandSurface *surface)
MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
if (buffer)
return cogl_texture_get_width (surface->texture);
return meta_multi_texture_get_width (surface->texture);
else
return 0;
}
@@ -252,7 +252,7 @@ get_buffer_height (MetaWaylandSurface *surface)
MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
if (buffer)
return cogl_texture_get_height (surface->texture);
return meta_multi_texture_get_height (surface->texture);
else
return 0;
}
@@ -658,7 +658,7 @@ meta_wayland_surface_apply_state (MetaWaylandSurface *surface,
}
else
{
cogl_clear_object (&surface->texture);
g_clear_object (&surface->texture);
}
/* If the newly attached buffer is going to be accessed directly without
@@ -1277,7 +1277,7 @@ wl_surface_destructor (struct wl_resource *resource)
if (surface->buffer_held)
meta_wayland_surface_unref_buffer_use_count (surface);
g_clear_pointer (&surface->texture, cogl_object_unref);
g_clear_object (&surface->texture);
g_clear_object (&surface->buffer_ref.buffer);
g_clear_object (&surface->cached_state);
@@ -1854,7 +1854,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->texture;

View File

@@ -153,7 +153,7 @@ struct _MetaWaylandSurface
GHashTable *outputs_to_destroy_notify_id;
MetaMonitorTransform buffer_transform;
CoglTexture *texture;
MetaMultiTexture *texture;
/* Buffer reference state. */
struct {
@@ -327,7 +327,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);
MetaSurfaceActor * meta_wayland_surface_get_actor (MetaWaylandSurface *surface);