mirror of
https://github.com/brl/mutter.git
synced 2024-11-28 19:10:43 -05:00
cogl: Add CoglMultiPlaneTexture for complex formats
Mutter always assumed that any texture it got was representable by a `CoglTexture`, which does not have this kind of concept. This also has the useful feature that each `CoglTexture` corresponds to a single layer in a `CoglPipeline`. To deal with this, we introduce a new object: a `CoglMultiPlaneTexture` consists of multiple `CoglTexture`s, each representing a plane in the texture we got. It also provides knows when to use a CoglPixelFormatConversion.
This commit is contained in:
parent
89111517bd
commit
f8747a2fe2
157
cogl/cogl/cogl-multi-plane-texture.c
Normal file
157
cogl/cogl/cogl-multi-plane-texture.c
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cogl-config.h"
|
||||||
|
|
||||||
|
#include "cogl-object-private.h"
|
||||||
|
#include "cogl-multi-plane-texture.h"
|
||||||
|
#include "cogl-gtype-private.h"
|
||||||
|
#include "cogl-texture-private.h"
|
||||||
|
#include "cogl-texture-2d-sliced.h"
|
||||||
|
|
||||||
|
struct _CoglMultiPlaneTexture
|
||||||
|
{
|
||||||
|
CoglObject _parent;
|
||||||
|
|
||||||
|
CoglPixelFormat format;
|
||||||
|
|
||||||
|
uint8_t n_planes;
|
||||||
|
CoglTexture **planes;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_multi_plane_texture_free (CoglMultiPlaneTexture *self);
|
||||||
|
|
||||||
|
COGL_OBJECT_DEFINE (MultiPlaneTexture, multi_plane_texture);
|
||||||
|
COGL_GTYPE_DEFINE_CLASS (MultiPlaneTexture, multi_plane_texture);
|
||||||
|
|
||||||
|
|
||||||
|
CoglPixelFormat
|
||||||
|
cogl_multi_plane_texture_get_format (CoglMultiPlaneTexture *self)
|
||||||
|
{
|
||||||
|
return self->format;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t
|
||||||
|
cogl_multi_plane_texture_get_n_planes (CoglMultiPlaneTexture *self)
|
||||||
|
{
|
||||||
|
return self->n_planes;
|
||||||
|
}
|
||||||
|
|
||||||
|
CoglTexture *
|
||||||
|
cogl_multi_plane_texture_get_plane (CoglMultiPlaneTexture *self, guint index)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (self->n_planes > 0, NULL);
|
||||||
|
g_return_val_if_fail (index < self->n_planes, NULL);
|
||||||
|
|
||||||
|
return self->planes[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
CoglTexture **
|
||||||
|
cogl_multi_plane_texture_get_planes (CoglMultiPlaneTexture *self)
|
||||||
|
{
|
||||||
|
return self->planes;
|
||||||
|
}
|
||||||
|
|
||||||
|
guint
|
||||||
|
cogl_multi_plane_texture_get_width (CoglMultiPlaneTexture *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (self->n_planes > 0, 0);
|
||||||
|
|
||||||
|
return cogl_texture_get_width (self->planes[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
guint
|
||||||
|
cogl_multi_plane_texture_get_height (CoglMultiPlaneTexture *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (self->n_planes > 0, 0);
|
||||||
|
|
||||||
|
return cogl_texture_get_height (self->planes[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_multi_plane_texture_free (CoglMultiPlaneTexture *self)
|
||||||
|
{
|
||||||
|
uint8_t i = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < self->n_planes; i++)
|
||||||
|
cogl_object_unref (self->planes[i]);
|
||||||
|
|
||||||
|
g_free (self->planes);
|
||||||
|
}
|
||||||
|
|
||||||
|
CoglMultiPlaneTexture *
|
||||||
|
cogl_multi_plane_texture_new (CoglPixelFormat format,
|
||||||
|
CoglTexture **planes, uint8_t n_planes)
|
||||||
|
{
|
||||||
|
CoglMultiPlaneTexture *self = g_slice_new0 (CoglMultiPlaneTexture);
|
||||||
|
|
||||||
|
_cogl_multi_plane_texture_object_new (self);
|
||||||
|
|
||||||
|
self->format = format;
|
||||||
|
self->n_planes = n_planes;
|
||||||
|
self->planes = planes;
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
CoglMultiPlaneTexture *
|
||||||
|
cogl_multi_plane_texture_new_single_plane (CoglPixelFormat format,
|
||||||
|
CoglTexture *plane)
|
||||||
|
{
|
||||||
|
CoglMultiPlaneTexture *self = g_slice_new0 (CoglMultiPlaneTexture);
|
||||||
|
|
||||||
|
_cogl_multi_plane_texture_object_new (self);
|
||||||
|
|
||||||
|
self->format = format;
|
||||||
|
self->n_planes = 1;
|
||||||
|
self->planes = g_malloc (sizeof (CoglTexture *));
|
||||||
|
self->planes[0] = plane;
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
cogl_multi_plane_texture_to_string (CoglMultiPlaneTexture *self)
|
||||||
|
{
|
||||||
|
g_autoptr(GString) str = NULL;
|
||||||
|
g_autofree char *ret = NULL;
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
str = g_string_new ("");
|
||||||
|
g_string_append_printf (str, "CoglMultiPlaneTexture (%p) {\n", self);
|
||||||
|
g_string_append_printf (str, " .format = %s;\n", cogl_pixel_format_to_string (self->format));
|
||||||
|
g_string_append_printf (str, " .n_planes = %u;\n", self->n_planes);
|
||||||
|
g_string_append (str, " .planes = {\n");
|
||||||
|
|
||||||
|
for (i = 0; i < self->n_planes; i++)
|
||||||
|
{
|
||||||
|
CoglTexture *plane = self->planes[i];
|
||||||
|
|
||||||
|
g_string_append_printf (str, " (%p) { .format = %s },\n",
|
||||||
|
plane,
|
||||||
|
cogl_pixel_format_to_string (_cogl_texture_get_format (plane)));
|
||||||
|
}
|
||||||
|
|
||||||
|
g_string_append (str, " }\n");
|
||||||
|
g_string_append (str, "}");
|
||||||
|
|
||||||
|
ret = g_string_free (g_steal_pointer (&str), FALSE);
|
||||||
|
return g_steal_pointer (&ret);
|
||||||
|
}
|
187
cogl/cogl/cogl-multi-plane-texture.h
Normal file
187
cogl/cogl/cogl-multi-plane-texture.h
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
/*
|
||||||
|
* 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 __COGL_MULTI_PLANE_TEXTURE_H__
|
||||||
|
#define __COGL_MULTI_PLANE_TEXTURE_H__
|
||||||
|
|
||||||
|
#include "cogl/cogl-texture.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:cogl-multi-plane-texture
|
||||||
|
* @title: CoglMultiPlaneTexture
|
||||||
|
* @short_description: A non-primitive texture that can have multiple planes.
|
||||||
|
*
|
||||||
|
* #CoglMultiPlaneTexture 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 #CoglMultiPlaneTexture is the following:
|
||||||
|
* - Each plane 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
|
||||||
|
* #CoglMultiPlaneTexture 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 cogl_multi_plane_texture_get_width() and its analogous version
|
||||||
|
* for the height to get the correct size of the texture.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct _CoglMultiPlaneTexture CoglMultiPlaneTexture;
|
||||||
|
#define COGL_MULTI_PLANE_TEXTURE(tex) ((CoglMultiPlaneTexture *) tex)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_multi_plane_texture_get_gtype:
|
||||||
|
*
|
||||||
|
* Returns: a #GType that can be used with the GLib type system.
|
||||||
|
*/
|
||||||
|
GType cogl_multi_plane_texture_get_gtype (void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_is_multi_plane_texture:
|
||||||
|
* @object: A #CoglObject pointer
|
||||||
|
*
|
||||||
|
* Gets whether the given @object references an existing CoglMultiPlaneTexture.
|
||||||
|
*
|
||||||
|
* Return value: %TRUE if the @object references a #CoglMultiPlaneTexture,
|
||||||
|
* %FALSE otherwise
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
cogl_is_multi_plane_texture (void *object);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_multi_plane_texture_new:
|
||||||
|
* @format: The format of the #CoglMultiPlaneTexture
|
||||||
|
* @planes: (transfer full): The actual planes of the texture
|
||||||
|
* @n_planes: The number of planes
|
||||||
|
*
|
||||||
|
* Creates a #CoglMultiPlaneTexture with the given @format. Each of the
|
||||||
|
* #CoglTexture<!-- -->s represents a plane.
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): A new #CoglMultiPlaneTexture. Use
|
||||||
|
* cogl_object_unref() when you're done with it.
|
||||||
|
*/
|
||||||
|
CoglMultiPlaneTexture * cogl_multi_plane_texture_new (CoglPixelFormat format,
|
||||||
|
CoglTexture **planes,
|
||||||
|
uint8_t n_planes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_multi_plane_texture_new_single_plane:
|
||||||
|
* @format: The format of the #CoglMultiPlaneTexture
|
||||||
|
* @plane: (transfer full): The actual planes of the texture
|
||||||
|
*
|
||||||
|
* Creates a #CoglMultiPlaneTexture for a "simple" texture, i.e. with only one
|
||||||
|
* plane.
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): A new #CoglMultiPlaneTexture. Use
|
||||||
|
* cogl_object_unref() when you're done with it.
|
||||||
|
*/
|
||||||
|
CoglMultiPlaneTexture * cogl_multi_plane_texture_new_single_plane (CoglPixelFormat format,
|
||||||
|
CoglTexture *plane);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_multi_plane_texture_get_format:
|
||||||
|
* @self: a #CoglMultiPlaneTexture
|
||||||
|
*
|
||||||
|
* Returns the pixel format that is used by this texture.
|
||||||
|
*
|
||||||
|
* Returns: The pixel format that is used by this #CoglMultiPlaneTexture.
|
||||||
|
*/
|
||||||
|
CoglPixelFormat cogl_multi_plane_texture_get_format (CoglMultiPlaneTexture *self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_multi_plane_texture_get_n_planes:
|
||||||
|
* @self: a #CoglMultiPlaneTexture
|
||||||
|
*
|
||||||
|
* Returns the number of planes for this texture. Note that this is entirely
|
||||||
|
* dependent on the #CoglPixelFormat that is used. For example, simple RGB
|
||||||
|
* textures will have a single plane, while some more convoluted formats like
|
||||||
|
* NV12 and YUV 4:4:4 can have 2 and 3 planes respectively.
|
||||||
|
*
|
||||||
|
* Returns: The number of planes in this #CoglMultiPlaneTexture.
|
||||||
|
*/
|
||||||
|
uint8_t cogl_multi_plane_texture_get_n_planes (CoglMultiPlaneTexture *self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_multi_plane_texture_get_plane:
|
||||||
|
* @self: a #CoglMultiPlaneTexture
|
||||||
|
* @index: the index of the plane
|
||||||
|
*
|
||||||
|
* Returns the n'th plane of the #CoglMultiPlaneTexture. Note that it is a
|
||||||
|
* programming error to use with an index larger than
|
||||||
|
* cogl_multi_plane_texture_get_n_planes().
|
||||||
|
*
|
||||||
|
* Returns: (transfer none): The plane at the given @index.
|
||||||
|
*/
|
||||||
|
CoglTexture * cogl_multi_plane_texture_get_plane (CoglMultiPlaneTexture *self,
|
||||||
|
guint index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_multi_plane_texture_get_planes:
|
||||||
|
* @self: a #CoglMultiPlaneTexture
|
||||||
|
*
|
||||||
|
* Returns all planes of the #CoglMultiPlaneTexture.
|
||||||
|
*
|
||||||
|
* Returns: (transfer none): The planes of this texture.
|
||||||
|
*/
|
||||||
|
CoglTexture ** cogl_multi_plane_texture_get_planes (CoglMultiPlaneTexture *self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_multi_plane_texture_get_width:
|
||||||
|
* @self: a #CoglMultiPlaneTexture
|
||||||
|
*
|
||||||
|
* Returns the width of the #CoglMultiPlaneTexture. 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.
|
||||||
|
*/
|
||||||
|
guint cogl_multi_plane_texture_get_width (CoglMultiPlaneTexture *self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_multi_plane_texture_get_height:
|
||||||
|
* @self: a #CoglMultiPlaneTexture
|
||||||
|
*
|
||||||
|
* Returns the height of the #CoglMultiPlaneTexture. 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.
|
||||||
|
*/
|
||||||
|
guint cogl_multi_plane_texture_get_height (CoglMultiPlaneTexture *self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_multi_plane_texture_to_string:
|
||||||
|
* @self: a #CoglMultiPlaneTexture
|
||||||
|
*
|
||||||
|
* 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 * cogl_multi_plane_texture_to_string (CoglMultiPlaneTexture *self);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif
|
@ -239,6 +239,7 @@ cogl_egl_texture_2d_new_from_image (CoglContext *ctx,
|
|||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
CoglPixelFormat format,
|
CoglPixelFormat format,
|
||||||
|
CoglTextureComponents components,
|
||||||
EGLImageKHR image,
|
EGLImageKHR image,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
@ -263,6 +264,9 @@ cogl_egl_texture_2d_new_from_image (CoglContext *ctx,
|
|||||||
|
|
||||||
tex = _cogl_texture_2d_create_base (ctx, width, height, format, loader);
|
tex = _cogl_texture_2d_create_base (ctx, width, height, format, loader);
|
||||||
|
|
||||||
|
/* Make sure we've set the right components before allocating */
|
||||||
|
cogl_texture_set_components (COGL_TEXTURE (tex), components);
|
||||||
|
|
||||||
if (!cogl_texture_allocate (COGL_TEXTURE (tex), error))
|
if (!cogl_texture_allocate (COGL_TEXTURE (tex), error))
|
||||||
{
|
{
|
||||||
cogl_object_unref (tex);
|
cogl_object_unref (tex);
|
||||||
|
@ -218,6 +218,7 @@ cogl_egl_texture_2d_new_from_image (CoglContext *ctx,
|
|||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
CoglPixelFormat format,
|
CoglPixelFormat format,
|
||||||
|
CoglTextureComponents components,
|
||||||
EGLImageKHR image,
|
EGLImageKHR image,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@
|
|||||||
#include <cogl/cogl1-context.h>
|
#include <cogl/cogl1-context.h>
|
||||||
#include <cogl/cogl-bitmap.h>
|
#include <cogl/cogl-bitmap.h>
|
||||||
#include <cogl/cogl-color.h>
|
#include <cogl/cogl-color.h>
|
||||||
|
#include <cogl/cogl-pixel-format-conversion.h>
|
||||||
#include <cogl/cogl-matrix.h>
|
#include <cogl/cogl-matrix.h>
|
||||||
#include <cogl/cogl-matrix-stack.h>
|
#include <cogl/cogl-matrix-stack.h>
|
||||||
#include <cogl/cogl-offscreen.h>
|
#include <cogl/cogl-offscreen.h>
|
||||||
@ -108,6 +109,7 @@
|
|||||||
#include <cogl/cogl-sub-texture.h>
|
#include <cogl/cogl-sub-texture.h>
|
||||||
#include <cogl/cogl-atlas-texture.h>
|
#include <cogl/cogl-atlas-texture.h>
|
||||||
#include <cogl/cogl-meta-texture.h>
|
#include <cogl/cogl-meta-texture.h>
|
||||||
|
#include <cogl/cogl-multi-plane-texture.h>
|
||||||
#include <cogl/cogl-primitive-texture.h>
|
#include <cogl/cogl-primitive-texture.h>
|
||||||
#include <cogl/cogl-index-buffer.h>
|
#include <cogl/cogl-index-buffer.h>
|
||||||
#include <cogl/cogl-attribute-buffer.h>
|
#include <cogl/cogl-attribute-buffer.h>
|
||||||
|
@ -82,6 +82,7 @@ cogl_headers = [
|
|||||||
'cogl-color.h',
|
'cogl-color.h',
|
||||||
'cogl-framebuffer.h',
|
'cogl-framebuffer.h',
|
||||||
'cogl-matrix.h',
|
'cogl-matrix.h',
|
||||||
|
'cogl-multi-plane-texture.h',
|
||||||
'cogl-object.h',
|
'cogl-object.h',
|
||||||
'cogl-offscreen.h',
|
'cogl-offscreen.h',
|
||||||
'cogl-onscreen.h',
|
'cogl-onscreen.h',
|
||||||
@ -322,6 +323,7 @@ cogl_sources = [
|
|||||||
'cogl-atlas-texture-private.h',
|
'cogl-atlas-texture-private.h',
|
||||||
'cogl-atlas-texture.c',
|
'cogl-atlas-texture.c',
|
||||||
'cogl-meta-texture.c',
|
'cogl-meta-texture.c',
|
||||||
|
'cogl-multi-plane-texture.c',
|
||||||
'cogl-primitive-texture.c',
|
'cogl-primitive-texture.c',
|
||||||
'cogl-blit.h',
|
'cogl-blit.h',
|
||||||
'cogl-blit.c',
|
'cogl-blit.c',
|
||||||
|
@ -800,6 +800,7 @@ _cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap)
|
|||||||
tex->width,
|
tex->width,
|
||||||
tex->height,
|
tex->height,
|
||||||
texture_format,
|
texture_format,
|
||||||
|
COGL_TEXTURE_COMPONENTS_RGBA,
|
||||||
egl_tex_pixmap->image,
|
egl_tex_pixmap->image,
|
||||||
NULL));
|
NULL));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user