mirror of
https://github.com/brl/mutter.git
synced 2024-11-21 15:40:41 -05:00
WIP: wayland: add basic support for non-RGBA textures
Up until now, we didn't support sending YUV textures to the Wayland server. This was for several reasons: * We draw onto an RGBA framebuffer, so any other color format needs to be converted to that color space. Since we don't want to lose a lot of performance, this is ideally done on the GPU (using shaders). * YUV formats can consist of several planes (for example NV12, a common format in decoded video frames consists of a Y-plane and a subsampled UV-plane). Mutter always assumed that any texture it got was representable by a `CoglTexture`, which does not have this kind of concept. To deal with this, we introduce a new "texture": a `CoglMultiPlaneTexture` which consists of multiple CoglTextures, each representing a plane in the texture we got. It also provides support for CoglSnippets which can convert the colorspace if necessary. What changes are in this commit: * Introduce a new CoglMultiPlaneTexture object. Right now it is not implemented as a CoglTexture to prevent any confusion (but it is somewhat related to CoglMetaTexture) * Added some extra values to the CoglPixelFormat enum that deal with YUV * Make the necessary changes in MetaWaylandBuffer, so that it knows how to deal with incoming buffers (for example EGLImages and shm buffers) * This also introduces some changes in MetaDmaBuf, as that is also a different kind of buffer we can receive from wayland. Acknowledgements * There was a lot of prior art already done by the authors of Weston, CoglGstVideoSink and ClutterGstSink * My employer Barco for allowing me to work on this
This commit is contained in:
parent
d3ed857ebc
commit
a3fb239344
@ -320,7 +320,37 @@ _cogl_bitmap_needs_short_temp_buffer (CoglPixelFormat format)
|
|||||||
case COGL_PIXEL_FORMAT_DEPTH_32:
|
case COGL_PIXEL_FORMAT_DEPTH_32:
|
||||||
case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
|
case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
|
||||||
case COGL_PIXEL_FORMAT_ANY:
|
case COGL_PIXEL_FORMAT_ANY:
|
||||||
|
/* No support for YUV or multi-plane formats */
|
||||||
case COGL_PIXEL_FORMAT_YUV:
|
case COGL_PIXEL_FORMAT_YUV:
|
||||||
|
case COGL_PIXEL_FORMAT_YUYV:
|
||||||
|
case COGL_PIXEL_FORMAT_YVYU:
|
||||||
|
case COGL_PIXEL_FORMAT_UYVY:
|
||||||
|
case COGL_PIXEL_FORMAT_VYUY:
|
||||||
|
case COGL_PIXEL_FORMAT_AYUV:
|
||||||
|
case COGL_PIXEL_FORMAT_XRGB88888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_XBGR88888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_RGBX88888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_BGRX88888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_RGB888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_BGR888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_RGB565_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_BGR565_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_NV12:
|
||||||
|
case COGL_PIXEL_FORMAT_NV21:
|
||||||
|
case COGL_PIXEL_FORMAT_NV16:
|
||||||
|
case COGL_PIXEL_FORMAT_NV61:
|
||||||
|
case COGL_PIXEL_FORMAT_NV24:
|
||||||
|
case COGL_PIXEL_FORMAT_NV42:
|
||||||
|
case COGL_PIXEL_FORMAT_YUV410:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU410:
|
||||||
|
case COGL_PIXEL_FORMAT_YUV411:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU411:
|
||||||
|
case COGL_PIXEL_FORMAT_YUV420:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU420:
|
||||||
|
case COGL_PIXEL_FORMAT_YUV422:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU422:
|
||||||
|
case COGL_PIXEL_FORMAT_YUV444:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU444:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
|
|
||||||
case COGL_PIXEL_FORMAT_A_8:
|
case COGL_PIXEL_FORMAT_A_8:
|
||||||
|
@ -400,7 +400,37 @@ G_PASTE (_cogl_unpack_, component_size) (CoglPixelFormat format,
|
|||||||
case COGL_PIXEL_FORMAT_DEPTH_32:
|
case COGL_PIXEL_FORMAT_DEPTH_32:
|
||||||
case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
|
case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
|
||||||
case COGL_PIXEL_FORMAT_ANY:
|
case COGL_PIXEL_FORMAT_ANY:
|
||||||
|
/* No support for YUV or multi-plane formats */
|
||||||
case COGL_PIXEL_FORMAT_YUV:
|
case COGL_PIXEL_FORMAT_YUV:
|
||||||
|
case COGL_PIXEL_FORMAT_YUYV:
|
||||||
|
case COGL_PIXEL_FORMAT_YVYU:
|
||||||
|
case COGL_PIXEL_FORMAT_UYVY:
|
||||||
|
case COGL_PIXEL_FORMAT_VYUY:
|
||||||
|
case COGL_PIXEL_FORMAT_AYUV:
|
||||||
|
case COGL_PIXEL_FORMAT_XRGB88888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_XBGR88888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_RGBX88888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_BGRX88888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_RGB888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_BGR888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_RGB565_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_BGR565_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_NV12:
|
||||||
|
case COGL_PIXEL_FORMAT_NV21:
|
||||||
|
case COGL_PIXEL_FORMAT_NV16:
|
||||||
|
case COGL_PIXEL_FORMAT_NV61:
|
||||||
|
case COGL_PIXEL_FORMAT_NV24:
|
||||||
|
case COGL_PIXEL_FORMAT_NV42:
|
||||||
|
case COGL_PIXEL_FORMAT_YUV410:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU410:
|
||||||
|
case COGL_PIXEL_FORMAT_YUV411:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU411:
|
||||||
|
case COGL_PIXEL_FORMAT_YUV420:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU420:
|
||||||
|
case COGL_PIXEL_FORMAT_YUV422:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU422:
|
||||||
|
case COGL_PIXEL_FORMAT_YUV444:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU444:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -761,7 +791,37 @@ G_PASTE (_cogl_pack_, component_size) (CoglPixelFormat format,
|
|||||||
case COGL_PIXEL_FORMAT_DEPTH_32:
|
case COGL_PIXEL_FORMAT_DEPTH_32:
|
||||||
case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
|
case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
|
||||||
case COGL_PIXEL_FORMAT_ANY:
|
case COGL_PIXEL_FORMAT_ANY:
|
||||||
|
/* No support for YUV or multi-plane formats */
|
||||||
case COGL_PIXEL_FORMAT_YUV:
|
case COGL_PIXEL_FORMAT_YUV:
|
||||||
|
case COGL_PIXEL_FORMAT_YUYV:
|
||||||
|
case COGL_PIXEL_FORMAT_YVYU:
|
||||||
|
case COGL_PIXEL_FORMAT_UYVY:
|
||||||
|
case COGL_PIXEL_FORMAT_VYUY:
|
||||||
|
case COGL_PIXEL_FORMAT_AYUV:
|
||||||
|
case COGL_PIXEL_FORMAT_XRGB88888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_XBGR88888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_RGBX88888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_BGRX88888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_RGB888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_BGR888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_RGB565_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_BGR565_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_NV12:
|
||||||
|
case COGL_PIXEL_FORMAT_NV21:
|
||||||
|
case COGL_PIXEL_FORMAT_NV16:
|
||||||
|
case COGL_PIXEL_FORMAT_NV61:
|
||||||
|
case COGL_PIXEL_FORMAT_NV24:
|
||||||
|
case COGL_PIXEL_FORMAT_NV42:
|
||||||
|
case COGL_PIXEL_FORMAT_YUV410:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU410:
|
||||||
|
case COGL_PIXEL_FORMAT_YUV411:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU411:
|
||||||
|
case COGL_PIXEL_FORMAT_YUV420:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU420:
|
||||||
|
case COGL_PIXEL_FORMAT_YUV422:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU422:
|
||||||
|
case COGL_PIXEL_FORMAT_YUV444:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU444:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
252
cogl/cogl/cogl-multi-plane-texture.c
Normal file
252
cogl/cogl/cogl-multi-plane-texture.c
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
guint 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
guint
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
guint 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, guint 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
CoglMultiPlaneTexture *
|
||||||
|
cogl_multi_plane_texture_new_from_bitmaps (CoglPixelFormat format,
|
||||||
|
CoglBitmap **bitmaps, guint n_planes,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
guint i = 0;
|
||||||
|
CoglMultiPlaneTexture *self = g_slice_new0 (CoglMultiPlaneTexture);
|
||||||
|
|
||||||
|
_cogl_multi_plane_texture_object_new (self);
|
||||||
|
|
||||||
|
self->format = format;
|
||||||
|
self->n_planes = n_planes;
|
||||||
|
self->planes = g_malloc (sizeof (CoglTexture *) * n_planes);
|
||||||
|
|
||||||
|
/* XXX convert to appropriate textures here */
|
||||||
|
for (i = 0; i < n_planes; i++)
|
||||||
|
{
|
||||||
|
CoglTexture *plane;
|
||||||
|
|
||||||
|
if (format == COGL_PIXEL_FORMAT_NV12)
|
||||||
|
{
|
||||||
|
/* Issue here: the data is inside the A coordinate, rather than the X coordinate */
|
||||||
|
if (i == 0)
|
||||||
|
_cogl_bitmap_set_format (bitmaps[i], COGL_PIXEL_FORMAT_G_8);
|
||||||
|
else
|
||||||
|
_cogl_bitmap_set_format (bitmaps[i], COGL_PIXEL_FORMAT_RG_88);
|
||||||
|
}
|
||||||
|
|
||||||
|
plane = COGL_TEXTURE (cogl_texture_2d_new_from_bitmap (bitmaps[i]));
|
||||||
|
|
||||||
|
if (format == COGL_PIXEL_FORMAT_NV12)
|
||||||
|
{
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
_cogl_texture_set_internal_format (plane, COGL_PIXEL_FORMAT_G_8);
|
||||||
|
_cogl_bitmap_set_format (bitmaps[i], COGL_PIXEL_FORMAT_G_8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_cogl_texture_set_internal_format (plane, COGL_PIXEL_FORMAT_RG_88);
|
||||||
|
_cogl_bitmap_set_format (bitmaps[i], COGL_PIXEL_FORMAT_RG_88);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* XXX Let's break everyting for non RGBA */
|
||||||
|
cogl_texture_set_components (plane, COGL_TEXTURE_COMPONENTS_RGBA);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cogl_texture_allocate (plane, error))
|
||||||
|
{
|
||||||
|
g_clear_pointer (&plane, cogl_object_unref);
|
||||||
|
|
||||||
|
/* There's a chance we failed due to the buffer being NPOT size.
|
||||||
|
* If so, try again with CoglTexture2DSliced (which does support this) */
|
||||||
|
if (g_error_matches (*error,
|
||||||
|
COGL_TEXTURE_ERROR,
|
||||||
|
COGL_TEXTURE_ERROR_SIZE))
|
||||||
|
{
|
||||||
|
CoglTexture2DSliced *plane_sliced;
|
||||||
|
|
||||||
|
g_clear_error (error);
|
||||||
|
|
||||||
|
plane_sliced =
|
||||||
|
cogl_texture_2d_sliced_new_from_bitmap (bitmaps[i],
|
||||||
|
COGL_TEXTURE_MAX_WASTE);
|
||||||
|
plane = COGL_TEXTURE (plane_sliced);
|
||||||
|
if (format == COGL_PIXEL_FORMAT_NV12)
|
||||||
|
{
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
_cogl_texture_set_internal_format (plane, COGL_PIXEL_FORMAT_G_8);
|
||||||
|
_cogl_bitmap_set_format (bitmaps[i], COGL_PIXEL_FORMAT_G_8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_cogl_texture_set_internal_format (plane, COGL_PIXEL_FORMAT_RG_88);
|
||||||
|
_cogl_bitmap_set_format (bitmaps[i], COGL_PIXEL_FORMAT_RG_88);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* XXX Let's break everyting for non RGBA */
|
||||||
|
cogl_texture_set_components (plane, COGL_TEXTURE_COMPONENTS_RGBA);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cogl_texture_allocate (plane, error))
|
||||||
|
cogl_clear_object (&plane);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cogl_object_unref (bitmaps[i]);
|
||||||
|
self->planes[i] = plane;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
gchar *
|
||||||
|
cogl_multi_plane_texture_to_string (CoglMultiPlaneTexture *self)
|
||||||
|
{
|
||||||
|
g_autoptr(GString) str = NULL;
|
||||||
|
g_autofree gchar *ret = NULL;
|
||||||
|
guint 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);
|
||||||
|
}
|
205
cogl/cogl/cogl-multi-plane-texture.h
Normal file
205
cogl/cogl/cogl-multi-plane-texture.h
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
/*
|
||||||
|
* 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,
|
||||||
|
guint 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_new_from_bitmaps:
|
||||||
|
* @format: The format of the new #CoglMultiPlaneTexture
|
||||||
|
* @bitmaps: (transfer full): The planes of the texture, each as a #CoglBitmap
|
||||||
|
* @n_planes: the number of planes the texture contains
|
||||||
|
* @error: (out): Will be set if an error occurred
|
||||||
|
*
|
||||||
|
* Creates a #CoglMultiPlaneTexture from the given bitmaps and makes sure the
|
||||||
|
* planes are uploaded to the GPU.
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): A new #CoglMultiPlaneTexture. Use
|
||||||
|
* cogl_object_unref() when you're done with it.
|
||||||
|
*/
|
||||||
|
CoglMultiPlaneTexture *
|
||||||
|
cogl_multi_plane_texture_new_from_bitmaps (CoglPixelFormat format,
|
||||||
|
CoglBitmap **bitmaps, guint n_planes,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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_format:
|
||||||
|
* @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.
|
||||||
|
*/
|
||||||
|
guint 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: 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.
|
||||||
|
*/
|
||||||
|
gchar * cogl_multi_plane_texture_to_string (CoglMultiPlaneTexture *self);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif
|
163
cogl/cogl/cogl-pixel-format-conversion.c
Normal file
163
cogl/cogl/cogl-pixel-format-conversion.c
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
/*
|
||||||
|
* 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-gtype-private.h"
|
||||||
|
#include "cogl-pixel-format-conversion.h"
|
||||||
|
#include "cogl-snippet.h"
|
||||||
|
#include "cogl-pipeline-layer-state.h"
|
||||||
|
#include "cogl-pipeline-state.h"
|
||||||
|
|
||||||
|
#define _COGL_YUV_TO_RGBA(res, y, u, v) \
|
||||||
|
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"
|
||||||
|
|
||||||
|
static const gchar nv12_to_rgba_shader[] =
|
||||||
|
"vec4\n"
|
||||||
|
"cogl_nv12_to_rgba (vec2 UV)\n"
|
||||||
|
"{\n"
|
||||||
|
" vec4 color;\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"
|
||||||
|
_COGL_YUV_TO_RGBA ("color", "y", "u", "v")
|
||||||
|
" return color;\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
static const gchar yuv_to_rgba_shader[] =
|
||||||
|
"vec4\n"
|
||||||
|
"cogl_yuv_to_rgba (vec2 UV)\n"
|
||||||
|
"{\n"
|
||||||
|
" vec4 color;\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"
|
||||||
|
_COGL_YUV_TO_RGBA ("color", "y", "u", "v")
|
||||||
|
" return color;\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
struct _CoglPixelFormatConversion
|
||||||
|
{
|
||||||
|
CoglObject _parent;
|
||||||
|
|
||||||
|
CoglSnippet *vertex_declaration_snippet;
|
||||||
|
CoglSnippet *fragment_declaration_snippet;
|
||||||
|
|
||||||
|
CoglSnippet *fragment_execution_snippet;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_pixel_format_conversion_free (CoglPixelFormatConversion *self);
|
||||||
|
|
||||||
|
COGL_OBJECT_DEFINE (PixelFormatConversion, pixel_format_conversion);
|
||||||
|
COGL_GTYPE_DEFINE_CLASS (PixelFormatConversion, pixel_format_conversion);
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_pixel_format_conversion_attach_to_pipeline (CoglPixelFormatConversion *self,
|
||||||
|
CoglPipeline *pipeline,
|
||||||
|
gint layer)
|
||||||
|
{
|
||||||
|
cogl_pipeline_add_snippet (pipeline, self->fragment_declaration_snippet);
|
||||||
|
cogl_pipeline_add_snippet (pipeline, self->vertex_declaration_snippet);
|
||||||
|
|
||||||
|
cogl_pipeline_add_layer_snippet (pipeline,
|
||||||
|
layer,
|
||||||
|
self->fragment_execution_snippet);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
get_cogl_snippets (CoglPixelFormat format,
|
||||||
|
CoglSnippet **vertex_snippet_out,
|
||||||
|
CoglSnippet **fragment_snippet_out,
|
||||||
|
CoglSnippet **layer_snippet_out)
|
||||||
|
{
|
||||||
|
const gchar *global_hook;
|
||||||
|
const gchar *layer_hook;
|
||||||
|
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case COGL_PIXEL_FORMAT_YUV444:
|
||||||
|
global_hook = yuv_to_rgba_shader;
|
||||||
|
layer_hook = "cogl_layer = cogl_yuv_to_rgba(cogl_tex_coord0_in.st);\n";
|
||||||
|
break;
|
||||||
|
case COGL_PIXEL_FORMAT_NV12:
|
||||||
|
/* XXX are we using Y_UV or Y_xUxV? Maybe check for RG support? */
|
||||||
|
global_hook = nv12_to_rgba_shader;
|
||||||
|
layer_hook = "cogl_layer = cogl_nv12_to_rgba(cogl_tex_coord0_in.st);\n";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
*vertex_snippet_out = NULL;
|
||||||
|
*fragment_snippet_out = NULL;
|
||||||
|
*layer_snippet_out = NULL;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*vertex_snippet_out = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX_GLOBALS,
|
||||||
|
global_hook,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
*fragment_snippet_out = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT_GLOBALS,
|
||||||
|
global_hook,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
*layer_snippet_out = cogl_snippet_new (COGL_SNIPPET_HOOK_LAYER_FRAGMENT,
|
||||||
|
NULL,
|
||||||
|
layer_hook);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_pixel_format_conversion_free (CoglPixelFormatConversion *self)
|
||||||
|
{
|
||||||
|
cogl_clear_object (&self->vertex_declaration_snippet);
|
||||||
|
cogl_clear_object (&self->fragment_declaration_snippet);
|
||||||
|
cogl_clear_object (&self->fragment_execution_snippet);
|
||||||
|
}
|
||||||
|
|
||||||
|
CoglPixelFormatConversion *
|
||||||
|
cogl_pixel_format_conversion_new (CoglPixelFormat format)
|
||||||
|
{
|
||||||
|
CoglPixelFormatConversion *self;
|
||||||
|
CoglSnippet *vertex_declaration_snippet;
|
||||||
|
CoglSnippet *fragment_declaration_snippet;
|
||||||
|
CoglSnippet *fragment_execution_snippet;
|
||||||
|
|
||||||
|
if (!get_cogl_snippets (format,
|
||||||
|
&vertex_declaration_snippet,
|
||||||
|
&fragment_declaration_snippet,
|
||||||
|
&fragment_execution_snippet))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
self = g_slice_new0 (CoglPixelFormatConversion);
|
||||||
|
_cogl_pixel_format_conversion_object_new (self);
|
||||||
|
|
||||||
|
self->vertex_declaration_snippet = vertex_declaration_snippet;
|
||||||
|
self->fragment_declaration_snippet = fragment_declaration_snippet;
|
||||||
|
self->fragment_execution_snippet = fragment_execution_snippet;
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
92
cogl/cogl/cogl-pixel-format-conversion.h
Normal file
92
cogl/cogl/cogl-pixel-format-conversion.h
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* 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_PIXEL_FORMAT_CONVERSION_H__
|
||||||
|
#define __COGL_PIXEL_FORMAT_CONVERSION_H__
|
||||||
|
|
||||||
|
#include "cogl/cogl-types.h"
|
||||||
|
#include "cogl/cogl-pipeline.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:cogl-color-space-conversion
|
||||||
|
* @title: CoglPixelFormatConversion
|
||||||
|
* @short_description: A collection of snippets to handle pixel_format conversion
|
||||||
|
*
|
||||||
|
* In some use cases, one might generate non-RGBA textures (e.g. YUV), which is
|
||||||
|
* problematic if you then have to composite them in to an RGBA framebuffer. In
|
||||||
|
* comes #CoglPixelFormatConversion, which you can attach to a #CoglPipeline to
|
||||||
|
* do this all for you. Internally, it consists of nothing more than a
|
||||||
|
* collection of #CoglSnippets which do the right thing for you.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct _CoglPixelFormatConversion CoglPixelFormatConversion;
|
||||||
|
#define COGL_PIXEL_FORMAT_CONVERSION(ptr) ((CoglPixelFormatConversion *) ptr)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_multiplane_texture_get_gtype:
|
||||||
|
*
|
||||||
|
* Returns: a #GType that can be used with the GLib type system.
|
||||||
|
*/
|
||||||
|
GType cogl_pixel_format_conversion_get_gtype (void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cogl_is_pixel_format_conversion:
|
||||||
|
* @object: A #CoglObject pointer
|
||||||
|
*
|
||||||
|
* Gets whether the given @object references an existing
|
||||||
|
* CoglPixelFormatConversion.
|
||||||
|
*
|
||||||
|
* Return value: %TRUE if the @object references a #CoglPixelFormatConversion,
|
||||||
|
* %FALSE otherwise
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
cogl_is_pixel_format_conversion (void *object);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_pixel_format_conversion_new:
|
||||||
|
* @format: The input format
|
||||||
|
*
|
||||||
|
* Creates a #CoglPixelFormatConversion to convert the given @formatro RGBA. If
|
||||||
|
* no such conversion is needed, it will return %NULL.
|
||||||
|
*
|
||||||
|
* Returns: (transfer full) (nullable): A new #CoglPixelFormatConversion, or
|
||||||
|
* %NULL if none is needed.
|
||||||
|
*/
|
||||||
|
CoglPixelFormatConversion * cogl_pixel_format_conversion_new (CoglPixelFormat format);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_pixel_format_conversion_attach_to_pipeline:
|
||||||
|
* @self: The #CoglPixelFormatConversion you want to add
|
||||||
|
* @pipeline: The #CoglPipeline which needs the color conversion
|
||||||
|
* @layer: The layer you want to perform the color space conversion at
|
||||||
|
*
|
||||||
|
* Adds color conversion to the given @pipeline at the given @layer.
|
||||||
|
*/
|
||||||
|
void cogl_pixel_format_conversion_attach_to_pipeline (CoglPixelFormatConversion *self,
|
||||||
|
CoglPipeline *pipeline,
|
||||||
|
int layer);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif
|
@ -43,6 +43,7 @@ typedef struct _CoglPixelFormatInfo
|
|||||||
const char *format_str;
|
const char *format_str;
|
||||||
int bpp; /* Bytes per pixel */
|
int bpp; /* Bytes per pixel */
|
||||||
int aligned; /* Aligned components? (-1 if n/a) */
|
int aligned; /* Aligned components? (-1 if n/a) */
|
||||||
|
uint8_t n_planes;
|
||||||
} CoglPixelFormatInfo;
|
} CoglPixelFormatInfo;
|
||||||
|
|
||||||
static const CoglPixelFormatInfo format_info_table[] = {
|
static const CoglPixelFormatInfo format_info_table[] = {
|
||||||
@ -50,187 +51,425 @@ static const CoglPixelFormatInfo format_info_table[] = {
|
|||||||
.cogl_format = COGL_PIXEL_FORMAT_ANY,
|
.cogl_format = COGL_PIXEL_FORMAT_ANY,
|
||||||
.format_str = "ANY",
|
.format_str = "ANY",
|
||||||
.bpp = 0,
|
.bpp = 0,
|
||||||
.aligned = -1
|
.aligned = -1,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_A_8,
|
.cogl_format = COGL_PIXEL_FORMAT_A_8,
|
||||||
.format_str = "A_8",
|
.format_str = "A_8",
|
||||||
.bpp = 1,
|
.bpp = 1,
|
||||||
.aligned = 1
|
.aligned = 1,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_RGB_565,
|
.cogl_format = COGL_PIXEL_FORMAT_RGB_565,
|
||||||
.format_str = "RGB_565",
|
.format_str = "RGB_565",
|
||||||
.bpp = 2,
|
.bpp = 2,
|
||||||
.aligned = 0
|
.aligned = 0,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_RGBA_4444,
|
.cogl_format = COGL_PIXEL_FORMAT_RGBA_4444,
|
||||||
.format_str = "RGBA_4444",
|
.format_str = "RGBA_4444",
|
||||||
.bpp = 2,
|
.bpp = 2,
|
||||||
.aligned = 0
|
.aligned = 0,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_RGBA_5551,
|
.cogl_format = COGL_PIXEL_FORMAT_RGBA_5551,
|
||||||
.format_str = "RGBA_5551",
|
.format_str = "RGBA_5551",
|
||||||
.bpp = 2,
|
.bpp = 2,
|
||||||
.aligned = 0
|
.aligned = 0,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_YUV,
|
.cogl_format = COGL_PIXEL_FORMAT_YUV,
|
||||||
.format_str = "YUV",
|
.format_str = "YUV",
|
||||||
.bpp = 0,
|
.bpp = 0,
|
||||||
.aligned = -1
|
.aligned = -1,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_G_8,
|
.cogl_format = COGL_PIXEL_FORMAT_G_8,
|
||||||
.format_str = "G_8",
|
.format_str = "G_8",
|
||||||
.bpp = 1,
|
.bpp = 1,
|
||||||
.aligned = 1
|
.aligned = 1,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_RG_88,
|
.cogl_format = COGL_PIXEL_FORMAT_RG_88,
|
||||||
.format_str = "RG_88",
|
.format_str = "RG_88",
|
||||||
.bpp = 2,
|
.bpp = 2,
|
||||||
.aligned = 1
|
.aligned = 1,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_RGB_888,
|
.cogl_format = COGL_PIXEL_FORMAT_RGB_888,
|
||||||
.format_str = "RGB_888",
|
.format_str = "RGB_888",
|
||||||
.bpp = 3,
|
.bpp = 3,
|
||||||
.aligned = 1
|
.aligned = 1,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_BGR_888,
|
.cogl_format = COGL_PIXEL_FORMAT_BGR_888,
|
||||||
.format_str = "BGR_888",
|
.format_str = "BGR_888",
|
||||||
.bpp = 3,
|
.bpp = 3,
|
||||||
.aligned = 1
|
.aligned = 1,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_RGBA_8888,
|
.cogl_format = COGL_PIXEL_FORMAT_RGBA_8888,
|
||||||
.format_str = "RGBA_8888",
|
.format_str = "RGBA_8888",
|
||||||
.bpp = 4,
|
.bpp = 4,
|
||||||
.aligned = 1
|
.aligned = 1,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_BGRA_8888,
|
.cogl_format = COGL_PIXEL_FORMAT_BGRA_8888,
|
||||||
.format_str = "BGRA_8888",
|
.format_str = "BGRA_8888",
|
||||||
.bpp = 4,
|
.bpp = 4,
|
||||||
.aligned = 1
|
.aligned = 1,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_ARGB_8888,
|
.cogl_format = COGL_PIXEL_FORMAT_ARGB_8888,
|
||||||
.format_str = "ARGB_8888",
|
.format_str = "ARGB_8888",
|
||||||
.bpp = 4,
|
.bpp = 4,
|
||||||
.aligned = 1
|
.aligned = 1,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_ABGR_8888,
|
.cogl_format = COGL_PIXEL_FORMAT_ABGR_8888,
|
||||||
.format_str = "ABGR_8888",
|
.format_str = "ABGR_8888",
|
||||||
.bpp = 4,
|
.bpp = 4,
|
||||||
.aligned = 1
|
.aligned = 1,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_RGBA_1010102,
|
.cogl_format = COGL_PIXEL_FORMAT_RGBA_1010102,
|
||||||
.format_str = "RGBA_1010102",
|
.format_str = "RGBA_1010102",
|
||||||
.bpp = 4,
|
.bpp = 4,
|
||||||
.aligned = 0
|
.aligned = 0,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_BGRA_1010102,
|
.cogl_format = COGL_PIXEL_FORMAT_BGRA_1010102,
|
||||||
.format_str = "BGRA_1010102",
|
.format_str = "BGRA_1010102",
|
||||||
.bpp = 4,
|
.bpp = 4,
|
||||||
.aligned = 0
|
.aligned = 0,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010,
|
.cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010,
|
||||||
.format_str = "ARGB_2101010",
|
.format_str = "ARGB_2101010",
|
||||||
.bpp = 4,
|
.bpp = 4,
|
||||||
.aligned = 0
|
.aligned = 0,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010,
|
.cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010,
|
||||||
.format_str = "ABGR_2101010",
|
.format_str = "ABGR_2101010",
|
||||||
.bpp = 4,
|
.bpp = 4,
|
||||||
.aligned = 0
|
.aligned = 0,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
.cogl_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||||
.format_str = "RGBA_8888_PRE",
|
.format_str = "RGBA_8888_PRE",
|
||||||
.bpp = 4,
|
.bpp = 4,
|
||||||
.aligned = 1
|
.aligned = 1,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_BGRA_8888_PRE,
|
.cogl_format = COGL_PIXEL_FORMAT_BGRA_8888_PRE,
|
||||||
.format_str = "BGRA_8888_PRE",
|
.format_str = "BGRA_8888_PRE",
|
||||||
.bpp = 4,
|
.bpp = 4,
|
||||||
.aligned = 1
|
.aligned = 1,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE,
|
.cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE,
|
||||||
.format_str = "ARGB_8888_PRE",
|
.format_str = "ARGB_8888_PRE",
|
||||||
.bpp = 4,
|
.bpp = 4,
|
||||||
.aligned = 1
|
.aligned = 1,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_ABGR_8888_PRE,
|
.cogl_format = COGL_PIXEL_FORMAT_ABGR_8888_PRE,
|
||||||
.format_str = "ABGR_8888_PRE",
|
.format_str = "ABGR_8888_PRE",
|
||||||
.bpp = 4,
|
.bpp = 4,
|
||||||
.aligned = 1
|
.aligned = 1,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_RGBA_4444_PRE,
|
.cogl_format = COGL_PIXEL_FORMAT_RGBA_4444_PRE,
|
||||||
.format_str = "RGBA_4444_PRE",
|
.format_str = "RGBA_4444_PRE",
|
||||||
.bpp = 2,
|
.bpp = 2,
|
||||||
.aligned = 0
|
.aligned = 0,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_RGBA_5551_PRE,
|
.cogl_format = COGL_PIXEL_FORMAT_RGBA_5551_PRE,
|
||||||
.format_str = "RGBA_5551_PRE",
|
.format_str = "RGBA_5551_PRE",
|
||||||
.bpp = 2,
|
.bpp = 2,
|
||||||
.aligned = 0
|
.aligned = 0,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_RGBA_1010102_PRE,
|
.cogl_format = COGL_PIXEL_FORMAT_RGBA_1010102_PRE,
|
||||||
.format_str = "RGBA_1010102_PRE",
|
.format_str = "RGBA_1010102_PRE",
|
||||||
.bpp = 4,
|
.bpp = 4,
|
||||||
.aligned = 0
|
.aligned = 0,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_BGRA_1010102_PRE,
|
.cogl_format = COGL_PIXEL_FORMAT_BGRA_1010102_PRE,
|
||||||
.format_str = "BGRA_1010102_PRE",
|
.format_str = "BGRA_1010102_PRE",
|
||||||
.bpp = 4,
|
.bpp = 4,
|
||||||
.aligned = 0
|
.aligned = 0,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010_PRE,
|
.cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010_PRE,
|
||||||
.format_str = "ARGB_2101010_PRE",
|
.format_str = "ARGB_2101010_PRE",
|
||||||
.bpp = 4,
|
.bpp = 4,
|
||||||
.aligned = 0
|
.aligned = 0,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010_PRE,
|
.cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010_PRE,
|
||||||
.format_str = "ABGR_2101010_PRE",
|
.format_str = "ABGR_2101010_PRE",
|
||||||
.bpp = 4,
|
.bpp = 4,
|
||||||
.aligned = 0
|
.aligned = 0,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_DEPTH_16,
|
.cogl_format = COGL_PIXEL_FORMAT_DEPTH_16,
|
||||||
.format_str = "DEPTH_16",
|
.format_str = "DEPTH_16",
|
||||||
.bpp = 2,
|
.bpp = 2,
|
||||||
.aligned = 1
|
.aligned = 1,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_DEPTH_32,
|
.cogl_format = COGL_PIXEL_FORMAT_DEPTH_32,
|
||||||
.format_str = "DEPTH_32",
|
.format_str = "DEPTH_32",
|
||||||
.bpp = 4,
|
.bpp = 4,
|
||||||
.aligned = 1
|
.aligned = 1,
|
||||||
|
.n_planes = 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.cogl_format = COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8,
|
.cogl_format = COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8,
|
||||||
.format_str = "DEPTH_24_STENCIL_8",
|
.format_str = "DEPTH_24_STENCIL_8",
|
||||||
.bpp = 4,
|
.bpp = 4,
|
||||||
.aligned = 1
|
.aligned = 1,
|
||||||
|
.n_planes = 1
|
||||||
|
},
|
||||||
|
/* Packed YUV */
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_YUYV,
|
||||||
|
.format_str = "YUYV",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_YVYU,
|
||||||
|
.format_str = "YVYU",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_UYVY,
|
||||||
|
.format_str = "UYVY",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_VYUY,
|
||||||
|
.format_str = "VYUY",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_AYUV,
|
||||||
|
.format_str = "AYUV",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
|
},
|
||||||
|
/* 2 plane RGB + A */
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_XRGB88888_A8,
|
||||||
|
.format_str = "XRGB88888_A8",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_XBGR88888_A8,
|
||||||
|
.format_str = "XBGR88888_A8",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_RGBX88888_A8,
|
||||||
|
.format_str = "RGBX88888_A8",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_BGRX88888_A8,
|
||||||
|
.format_str = "BGRX88888_A8",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_RGB888_A8,
|
||||||
|
.format_str = "RGB888_A8",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_BGR888_A8,
|
||||||
|
.format_str = "BGR888_A8",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_RGB565_A8,
|
||||||
|
.format_str = "RGB565_A8",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_BGR565_A8,
|
||||||
|
.format_str = "BGR565_A8",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
|
},
|
||||||
|
/* 2 plane YUV */
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_NV12,
|
||||||
|
.format_str = "NV12",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_NV21,
|
||||||
|
.format_str = "NV21",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_NV16,
|
||||||
|
.format_str = "NV16",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_NV61,
|
||||||
|
.format_str = "NV61",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_NV24,
|
||||||
|
.format_str = "NV24",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_NV42,
|
||||||
|
.format_str = "NV42",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
|
},
|
||||||
|
/* 3 plane YUV */
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_YUV410,
|
||||||
|
.format_str = "YUV410",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_YVU410,
|
||||||
|
.format_str = "YVU410",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_YUV411,
|
||||||
|
.format_str = "YUV411",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_YVU411,
|
||||||
|
.format_str = "YVU411",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_YUV420,
|
||||||
|
.format_str = "YUV420",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_YVU420,
|
||||||
|
.format_str = "YVU420",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_YUV422,
|
||||||
|
.format_str = "YUV422",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_YVU422,
|
||||||
|
.format_str = "YVU422",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_YUV444,
|
||||||
|
.format_str = "YUV444",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cogl_format = COGL_PIXEL_FORMAT_YVU444,
|
||||||
|
.format_str = "YVU444",
|
||||||
|
.bpp = -1,
|
||||||
|
.aligned = 0,
|
||||||
|
.n_planes = 2
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -268,6 +507,45 @@ _cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format)
|
|||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX document.
|
||||||
|
*
|
||||||
|
* XXX lol, this is even per macropixel, not per pixel :D
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
cogl_pixel_format_get_bits_per_pixel (CoglPixelFormat format, guint *bpp_out)
|
||||||
|
{
|
||||||
|
/* "old" formats */
|
||||||
|
if (format & (0xff << 24))
|
||||||
|
{
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case COGL_PIXEL_FORMAT_NV12:
|
||||||
|
case COGL_PIXEL_FORMAT_NV21:
|
||||||
|
bpp_out[0] = 8;
|
||||||
|
bpp_out[1] = 4;
|
||||||
|
break;
|
||||||
|
case COGL_PIXEL_FORMAT_YUV420:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU420:
|
||||||
|
bpp_out[0] = 8;
|
||||||
|
bpp_out[1] = 2;
|
||||||
|
bpp_out[2] = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_warning ("FIXME");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int bpp_lut[] = { 0, 1, 3, 4,
|
||||||
|
2, 2, 2, 0,
|
||||||
|
1, 2, 0, 0,
|
||||||
|
3, 4, 0, 0 };
|
||||||
|
|
||||||
|
bpp_out[0] = 8 * bpp_lut [format & 0xf];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Note: this also refers to the mapping defined above for
|
/* Note: this also refers to the mapping defined above for
|
||||||
* _cogl_pixel_format_get_bytes_per_pixel() */
|
* _cogl_pixel_format_get_bytes_per_pixel() */
|
||||||
gboolean
|
gboolean
|
||||||
@ -295,6 +573,105 @@ _cogl_pixel_format_is_endian_dependant (CoglPixelFormat format)
|
|||||||
return aligned;
|
return aligned;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
guint
|
||||||
|
cogl_pixel_format_get_n_planes (CoglPixelFormat format)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (format_info_table); i++)
|
||||||
|
{
|
||||||
|
if (format_info_table[i].cogl_format == format)
|
||||||
|
return format_info_table[i].n_planes;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_pixel_format_get_subsampling_factors (CoglPixelFormat format,
|
||||||
|
guint *horizontal_factors,
|
||||||
|
guint *vertical_factors)
|
||||||
|
{
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
/* Packed formats (single plane) */
|
||||||
|
default:
|
||||||
|
horizontal_factors[0] = 1;
|
||||||
|
vertical_factors[0] = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* 2 planes */
|
||||||
|
case COGL_PIXEL_FORMAT_NV12:
|
||||||
|
case COGL_PIXEL_FORMAT_NV21:
|
||||||
|
horizontal_factors[0] = 1;
|
||||||
|
vertical_factors[0] = 1;
|
||||||
|
horizontal_factors[1] = 2;
|
||||||
|
vertical_factors[1] = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case COGL_PIXEL_FORMAT_XRGB88888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_XBGR88888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_RGBX88888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_BGRX88888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_RGB888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_BGR888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_RGB565_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_BGR565_A8:
|
||||||
|
horizontal_factors[0] = 1;
|
||||||
|
vertical_factors[0] = 1;
|
||||||
|
horizontal_factors[1] = 1;
|
||||||
|
vertical_factors[1] = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* 3 planes */
|
||||||
|
case COGL_PIXEL_FORMAT_YUV410:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU410:
|
||||||
|
horizontal_factors[0] = 1;
|
||||||
|
vertical_factors[0] = 1;
|
||||||
|
horizontal_factors[1] = 4;
|
||||||
|
vertical_factors[1] = 4;
|
||||||
|
horizontal_factors[2] = 4;
|
||||||
|
vertical_factors[2] = 4;
|
||||||
|
break;
|
||||||
|
case COGL_PIXEL_FORMAT_YUV411:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU411:
|
||||||
|
horizontal_factors[0] = 1;
|
||||||
|
vertical_factors[0] = 1;
|
||||||
|
horizontal_factors[1] = 4;
|
||||||
|
vertical_factors[1] = 1;
|
||||||
|
horizontal_factors[2] = 4;
|
||||||
|
vertical_factors[2] = 1;
|
||||||
|
break;
|
||||||
|
case COGL_PIXEL_FORMAT_YUV420:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU420:
|
||||||
|
horizontal_factors[0] = 1;
|
||||||
|
vertical_factors[0] = 1;
|
||||||
|
horizontal_factors[1] = 2;
|
||||||
|
vertical_factors[1] = 2;
|
||||||
|
horizontal_factors[2] = 2;
|
||||||
|
vertical_factors[2] = 2;
|
||||||
|
break;
|
||||||
|
case COGL_PIXEL_FORMAT_YUV422:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU422:
|
||||||
|
horizontal_factors[0] = 1;
|
||||||
|
vertical_factors[0] = 1;
|
||||||
|
horizontal_factors[1] = 2;
|
||||||
|
vertical_factors[1] = 1;
|
||||||
|
horizontal_factors[2] = 2;
|
||||||
|
vertical_factors[2] = 1;
|
||||||
|
break;
|
||||||
|
case COGL_PIXEL_FORMAT_YUV444:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU444:
|
||||||
|
horizontal_factors[0] = 1;
|
||||||
|
vertical_factors[0] = 1;
|
||||||
|
horizontal_factors[1] = 1;
|
||||||
|
vertical_factors[1] = 1;
|
||||||
|
horizontal_factors[2] = 1;
|
||||||
|
vertical_factors[2] = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
cogl_pixel_format_to_string (CoglPixelFormat format)
|
cogl_pixel_format_to_string (CoglPixelFormat format)
|
||||||
{
|
{
|
||||||
|
@ -145,7 +145,7 @@ G_BEGIN_DECLS
|
|||||||
* @COGL_PIXEL_FORMAT_RGB_565: RGB, 16 bits
|
* @COGL_PIXEL_FORMAT_RGB_565: RGB, 16 bits
|
||||||
* @COGL_PIXEL_FORMAT_RGBA_4444: RGBA, 16 bits
|
* @COGL_PIXEL_FORMAT_RGBA_4444: RGBA, 16 bits
|
||||||
* @COGL_PIXEL_FORMAT_RGBA_5551: RGBA, 16 bits
|
* @COGL_PIXEL_FORMAT_RGBA_5551: RGBA, 16 bits
|
||||||
* @COGL_PIXEL_FORMAT_YUV: Not currently supported
|
* @COGL_PIXEL_FORMAT_YUV: Obsolete. See the other YUV-based formats.
|
||||||
* @COGL_PIXEL_FORMAT_G_8: Single luminance component
|
* @COGL_PIXEL_FORMAT_G_8: Single luminance component
|
||||||
* @COGL_PIXEL_FORMAT_RGB_888: RGB, 24 bits
|
* @COGL_PIXEL_FORMAT_RGB_888: RGB, 24 bits
|
||||||
* @COGL_PIXEL_FORMAT_BGR_888: BGR, 24 bits
|
* @COGL_PIXEL_FORMAT_BGR_888: BGR, 24 bits
|
||||||
@ -167,6 +167,35 @@ G_BEGIN_DECLS
|
|||||||
* @COGL_PIXEL_FORMAT_BGRA_1010102_PRE: Premultiplied BGRA, 32 bits, 10 bpc
|
* @COGL_PIXEL_FORMAT_BGRA_1010102_PRE: Premultiplied BGRA, 32 bits, 10 bpc
|
||||||
* @COGL_PIXEL_FORMAT_ARGB_2101010_PRE: Premultiplied ARGB, 32 bits, 10 bpc
|
* @COGL_PIXEL_FORMAT_ARGB_2101010_PRE: Premultiplied ARGB, 32 bits, 10 bpc
|
||||||
* @COGL_PIXEL_FORMAT_ABGR_2101010_PRE: Premultiplied ABGR, 32 bits, 10 bpc
|
* @COGL_PIXEL_FORMAT_ABGR_2101010_PRE: Premultiplied ABGR, 32 bits, 10 bpc
|
||||||
|
* @COGL_PIXEL_FORMAT_YUYV: YUYV, 32 bits, 16 bpc (Y), 8 bpc (U & V)
|
||||||
|
* @COGL_PIXEL_FORMAT_YVYU: YVYU, 32 bits, 16 bpc (Y), 8 bpc (V & U)
|
||||||
|
* @COGL_PIXEL_FORMAT_UYVY: UYVY, 32 bits, 16 bpc (Y), 8 bpc (V & U)
|
||||||
|
* @COGL_PIXEL_FORMAT_VYUY: VYUV, 32 bits, 16 bpc (Y), 8 bpc (V & U)
|
||||||
|
* @COGL_PIXEL_FORMAT_AYUV: AYUV, 32 bits, 8 bpc
|
||||||
|
* @COGL_PIXEL_FORMAT_XRGB88888_A8:
|
||||||
|
* @COGL_PIXEL_FORMAT_XBGR88888_A8:
|
||||||
|
* @COGL_PIXEL_FORMAT_RGBX88888_A8:
|
||||||
|
* @COGL_PIXEL_FORMAT_BGRX88888_A8:
|
||||||
|
* @COGL_PIXEL_FORMAT_RGB888_A8:
|
||||||
|
* @COGL_PIXEL_FORMAT_BGR888_A8:
|
||||||
|
* @COGL_PIXEL_FORMAT_RGB565_A8:
|
||||||
|
* @COGL_PIXEL_FORMAT_BGR565_A8:
|
||||||
|
* @COGL_PIXEL_FORMAT_NV12: 2 planes: 1 Y-plane, 1 UV-plane (2x2 subsampled)
|
||||||
|
* @COGL_PIXEL_FORMAT_NV21: 2 planes: 1 Y-plane, 1 VU-plane (2x2 subsampled)
|
||||||
|
* @COGL_PIXEL_FORMAT_NV16: 2 planes: 1 Y-plane, 1 UV-plane (2x1 subsampled)
|
||||||
|
* @COGL_PIXEL_FORMAT_NV61: 2 planes: 1 Y-plane, 1 VU-plane (2x1 subsampled)
|
||||||
|
* @COGL_PIXEL_FORMAT_NV24: 2 planes: 1 Y-plane, 1 UV-plane
|
||||||
|
* @COGL_PIXEL_FORMAT_NV42: 2 planes: 1 Y-plane, 1 VU-plane
|
||||||
|
* @COGL_PIXEL_FORMAT_YUV410: 3 planes: 1 Y-plane, 1 U-plane (4x4 subsampled), 1 V-plane (4x4 subsampled)
|
||||||
|
* @COGL_PIXEL_FORMAT_YVU410: 3 planes: 1 Y-plane, 1 V-plane (4x4 subsampled), 1 U-plane (4x4 subsampled)
|
||||||
|
* @COGL_PIXEL_FORMAT_YUV411: 3 planes: 1 Y-plane, 1 U-plane (4x1 subsampled), 1 V-plane (4x1 subsampled)
|
||||||
|
* @COGL_PIXEL_FORMAT_YVU411: 3 planes: 1 Y-plane, 1 V-plane (4x1 subsampled), 1 U-plane (4x1 subsampled)
|
||||||
|
* @COGL_PIXEL_FORMAT_YUV420: 3 planes: 1 Y-plane, 1 U-plane (2x2 subsampled), 1 V-plane (2x2 subsampled)
|
||||||
|
* @COGL_PIXEL_FORMAT_YVU420: 3 planes: 1 Y-plane, 1 V-plane (2x2 subsampled), 1 U-plane (2x2 subsampled)
|
||||||
|
* @COGL_PIXEL_FORMAT_YUV422: 3 planes: 1 Y-plane, 1 U-plane (2x1 subsampled), 1 V-plane (2x1 subsampled)
|
||||||
|
* @COGL_PIXEL_FORMAT_YVU422: 3 planes: 1 Y-plane, 1 V-plane (2x1 subsampled), 1 U-plane (2x1 subsampled)
|
||||||
|
* @COGL_PIXEL_FORMAT_YUV444: 3 planes: 1 Y-plane, 1 U-plane, 1 V-plane
|
||||||
|
* @COGL_PIXEL_FORMAT_YVU444: 3 planes: 1 Y-plane, 1 V-plane, 1 U-plane
|
||||||
*
|
*
|
||||||
* Pixel formats used by Cogl. For the formats with a byte per
|
* Pixel formats used by Cogl. For the formats with a byte per
|
||||||
* component, the order of the components specify the order in
|
* component, the order of the components specify the order in
|
||||||
@ -230,7 +259,50 @@ typedef enum /*< prefix=COGL_PIXEL_FORMAT >*/
|
|||||||
COGL_PIXEL_FORMAT_DEPTH_16 = (9 | COGL_DEPTH_BIT),
|
COGL_PIXEL_FORMAT_DEPTH_16 = (9 | COGL_DEPTH_BIT),
|
||||||
COGL_PIXEL_FORMAT_DEPTH_32 = (3 | COGL_DEPTH_BIT),
|
COGL_PIXEL_FORMAT_DEPTH_32 = (3 | COGL_DEPTH_BIT),
|
||||||
|
|
||||||
COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8 = (3 | COGL_DEPTH_BIT | COGL_STENCIL_BIT)
|
COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8 = (3 | COGL_DEPTH_BIT | COGL_STENCIL_BIT),
|
||||||
|
|
||||||
|
/* From here on out, we simply enumerate with sequential values in the most
|
||||||
|
* significant enum byte. See the comments above if you want to know why. */
|
||||||
|
|
||||||
|
/* The following list is basically synced with Linux's <drm_fourcc.h> */
|
||||||
|
|
||||||
|
/* Packed YUV */
|
||||||
|
COGL_PIXEL_FORMAT_YUYV = (1 << 24),
|
||||||
|
COGL_PIXEL_FORMAT_YVYU = (2 << 24),
|
||||||
|
COGL_PIXEL_FORMAT_UYVY = (3 << 24),
|
||||||
|
COGL_PIXEL_FORMAT_VYUY = (4 << 24),
|
||||||
|
|
||||||
|
COGL_PIXEL_FORMAT_AYUV = (5 << 24),
|
||||||
|
|
||||||
|
/* 2 plane RGB + A */
|
||||||
|
COGL_PIXEL_FORMAT_XRGB88888_A8 = ( 6 << 24),
|
||||||
|
COGL_PIXEL_FORMAT_XBGR88888_A8 = ( 7 << 24),
|
||||||
|
COGL_PIXEL_FORMAT_RGBX88888_A8 = ( 8 << 24),
|
||||||
|
COGL_PIXEL_FORMAT_BGRX88888_A8 = ( 9 << 24),
|
||||||
|
COGL_PIXEL_FORMAT_RGB888_A8 = (10 << 24),
|
||||||
|
COGL_PIXEL_FORMAT_BGR888_A8 = (11 << 24),
|
||||||
|
COGL_PIXEL_FORMAT_RGB565_A8 = (12 << 24),
|
||||||
|
COGL_PIXEL_FORMAT_BGR565_A8 = (13 << 24),
|
||||||
|
|
||||||
|
/* 2 plane YUV */
|
||||||
|
COGL_PIXEL_FORMAT_NV12 = (14 << 24),
|
||||||
|
COGL_PIXEL_FORMAT_NV21 = (15 << 24),
|
||||||
|
COGL_PIXEL_FORMAT_NV16 = (16 << 24),
|
||||||
|
COGL_PIXEL_FORMAT_NV61 = (17 << 24),
|
||||||
|
COGL_PIXEL_FORMAT_NV24 = (18 << 24),
|
||||||
|
COGL_PIXEL_FORMAT_NV42 = (19 << 24),
|
||||||
|
|
||||||
|
/* 3 plane YUV */
|
||||||
|
COGL_PIXEL_FORMAT_YUV410 = (20 << 24),
|
||||||
|
COGL_PIXEL_FORMAT_YVU410 = (21 << 24),
|
||||||
|
COGL_PIXEL_FORMAT_YUV411 = (22 << 24),
|
||||||
|
COGL_PIXEL_FORMAT_YVU411 = (23 << 24),
|
||||||
|
COGL_PIXEL_FORMAT_YUV420 = (24 << 24),
|
||||||
|
COGL_PIXEL_FORMAT_YVU420 = (25 << 24),
|
||||||
|
COGL_PIXEL_FORMAT_YUV422 = (26 << 24),
|
||||||
|
COGL_PIXEL_FORMAT_YVU422 = (27 << 24),
|
||||||
|
COGL_PIXEL_FORMAT_YUV444 = (28 << 24),
|
||||||
|
COGL_PIXEL_FORMAT_YVU444 = (29 << 24)
|
||||||
} CoglPixelFormat;
|
} CoglPixelFormat;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -284,6 +356,29 @@ _cogl_pixel_format_is_endian_dependant (CoglPixelFormat format);
|
|||||||
#define COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT(format) \
|
#define COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT(format) \
|
||||||
(((format) & COGL_A_BIT) && (format) != COGL_PIXEL_FORMAT_A_8)
|
(((format) & COGL_A_BIT) && (format) != COGL_PIXEL_FORMAT_A_8)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_pixel_format_get_n_planes:
|
||||||
|
* @format: The format for which to get the number of planes
|
||||||
|
*
|
||||||
|
* Returns the number of planes the given CoglPixelFormat specifies.
|
||||||
|
*/
|
||||||
|
guint
|
||||||
|
cogl_pixel_format_get_n_planes (CoglPixelFormat format);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_pixel_format_get_subsampling_factors:
|
||||||
|
* @format: The format to get the subsampling factors from.
|
||||||
|
*
|
||||||
|
* Returns the subsampling in both the horizontal as the vertical direction.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
cogl_pixel_format_get_subsampling_factors (CoglPixelFormat format,
|
||||||
|
guint *horizontal_factors,
|
||||||
|
guint *vertical_factors);
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_pixel_format_get_bits_per_pixel (CoglPixelFormat format, guint *bpp_out);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cogl_pixel_format_to_string:
|
* cogl_pixel_format_to_string:
|
||||||
* @format: a #CoglPixelFormat
|
* @format: a #CoglPixelFormat
|
||||||
|
@ -61,6 +61,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>
|
||||||
@ -112,6 +113,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>
|
||||||
|
@ -209,6 +209,8 @@ allocate_from_bitmap (CoglTexture2D *tex_2d,
|
|||||||
GLenum gl_format;
|
GLenum gl_format;
|
||||||
GLenum gl_type;
|
GLenum gl_type;
|
||||||
|
|
||||||
|
g_warning ("allocate_from_bitmap()");
|
||||||
|
|
||||||
internal_format =
|
internal_format =
|
||||||
_cogl_texture_determine_internal_format (tex, cogl_bitmap_get_format (bmp));
|
_cogl_texture_determine_internal_format (tex, cogl_bitmap_get_format (bmp));
|
||||||
|
|
||||||
@ -349,6 +351,8 @@ allocate_from_gl_foreign (CoglTexture2D *tex_2d,
|
|||||||
GLint gl_compressed = GL_FALSE;
|
GLint gl_compressed = GL_FALSE;
|
||||||
GLenum gl_int_format = 0;
|
GLenum gl_int_format = 0;
|
||||||
|
|
||||||
|
g_warning ("allocate_from_egl_image_foreign()");
|
||||||
|
|
||||||
if (!ctx->texture_driver->allows_foreign_gl_target (ctx, GL_TEXTURE_2D))
|
if (!ctx->texture_driver->allows_foreign_gl_target (ctx, GL_TEXTURE_2D))
|
||||||
{
|
{
|
||||||
_cogl_set_error (error,
|
_cogl_set_error (error,
|
||||||
|
@ -268,7 +268,37 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case COGL_PIXEL_FORMAT_ANY:
|
case COGL_PIXEL_FORMAT_ANY:
|
||||||
|
/* No support for YUV or multi-plane formats */
|
||||||
case COGL_PIXEL_FORMAT_YUV:
|
case COGL_PIXEL_FORMAT_YUV:
|
||||||
|
case COGL_PIXEL_FORMAT_YUYV:
|
||||||
|
case COGL_PIXEL_FORMAT_YVYU:
|
||||||
|
case COGL_PIXEL_FORMAT_UYVY:
|
||||||
|
case COGL_PIXEL_FORMAT_VYUY:
|
||||||
|
case COGL_PIXEL_FORMAT_AYUV:
|
||||||
|
case COGL_PIXEL_FORMAT_XRGB88888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_XBGR88888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_RGBX88888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_BGRX88888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_RGB888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_BGR888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_RGB565_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_BGR565_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_NV12:
|
||||||
|
case COGL_PIXEL_FORMAT_NV21:
|
||||||
|
case COGL_PIXEL_FORMAT_NV16:
|
||||||
|
case COGL_PIXEL_FORMAT_NV61:
|
||||||
|
case COGL_PIXEL_FORMAT_NV24:
|
||||||
|
case COGL_PIXEL_FORMAT_NV42:
|
||||||
|
case COGL_PIXEL_FORMAT_YUV410:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU410:
|
||||||
|
case COGL_PIXEL_FORMAT_YUV411:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU411:
|
||||||
|
case COGL_PIXEL_FORMAT_YUV420:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU420:
|
||||||
|
case COGL_PIXEL_FORMAT_YUV422:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU422:
|
||||||
|
case COGL_PIXEL_FORMAT_YUV444:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU444:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -210,6 +210,8 @@ _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx,
|
|||||||
int level_width;
|
int level_width;
|
||||||
int level_height;
|
int level_height;
|
||||||
|
|
||||||
|
g_warning ("uploading subregion to gl");
|
||||||
|
|
||||||
cogl_texture_get_gl_texture (texture, &gl_handle, &gl_target);
|
cogl_texture_get_gl_texture (texture, &gl_handle, &gl_target);
|
||||||
|
|
||||||
data = _cogl_bitmap_gl_bind (source_bmp, COGL_BUFFER_ACCESS_READ, 0, &internal_error);
|
data = _cogl_bitmap_gl_bind (source_bmp, COGL_BUFFER_ACCESS_READ, 0, &internal_error);
|
||||||
@ -314,6 +316,8 @@ _cogl_texture_driver_upload_to_gl (CoglContext *ctx,
|
|||||||
gboolean status = TRUE;
|
gboolean status = TRUE;
|
||||||
CoglError *internal_error = NULL;
|
CoglError *internal_error = NULL;
|
||||||
|
|
||||||
|
g_warning ("uploading to gl");
|
||||||
|
|
||||||
data = _cogl_bitmap_gl_bind (source_bmp,
|
data = _cogl_bitmap_gl_bind (source_bmp,
|
||||||
COGL_BUFFER_ACCESS_READ,
|
COGL_BUFFER_ACCESS_READ,
|
||||||
0, /* hints */
|
0, /* hints */
|
||||||
|
@ -198,7 +198,37 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case COGL_PIXEL_FORMAT_ANY:
|
case COGL_PIXEL_FORMAT_ANY:
|
||||||
|
/* No support for YUV or multi-plane formats */
|
||||||
case COGL_PIXEL_FORMAT_YUV:
|
case COGL_PIXEL_FORMAT_YUV:
|
||||||
|
case COGL_PIXEL_FORMAT_YUYV:
|
||||||
|
case COGL_PIXEL_FORMAT_YVYU:
|
||||||
|
case COGL_PIXEL_FORMAT_UYVY:
|
||||||
|
case COGL_PIXEL_FORMAT_VYUY:
|
||||||
|
case COGL_PIXEL_FORMAT_AYUV:
|
||||||
|
case COGL_PIXEL_FORMAT_XRGB88888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_XBGR88888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_RGBX88888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_BGRX88888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_RGB888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_BGR888_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_RGB565_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_BGR565_A8:
|
||||||
|
case COGL_PIXEL_FORMAT_NV12:
|
||||||
|
case COGL_PIXEL_FORMAT_NV21:
|
||||||
|
case COGL_PIXEL_FORMAT_NV16:
|
||||||
|
case COGL_PIXEL_FORMAT_NV61:
|
||||||
|
case COGL_PIXEL_FORMAT_NV24:
|
||||||
|
case COGL_PIXEL_FORMAT_NV42:
|
||||||
|
case COGL_PIXEL_FORMAT_YUV410:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU410:
|
||||||
|
case COGL_PIXEL_FORMAT_YUV411:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU411:
|
||||||
|
case COGL_PIXEL_FORMAT_YUV420:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU420:
|
||||||
|
case COGL_PIXEL_FORMAT_YUV422:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU422:
|
||||||
|
case COGL_PIXEL_FORMAT_YUV444:
|
||||||
|
case COGL_PIXEL_FORMAT_YVU444:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -89,6 +89,7 @@ cogl_headers = [
|
|||||||
'cogl-pipeline-state.h',
|
'cogl-pipeline-state.h',
|
||||||
'cogl-pipeline-layer-state.h',
|
'cogl-pipeline-layer-state.h',
|
||||||
'cogl-pixel-format.h',
|
'cogl-pixel-format.h',
|
||||||
|
'cogl-pixel-format-conversion.h',
|
||||||
'cogl-primitives.h',
|
'cogl-primitives.h',
|
||||||
'cogl-texture.h',
|
'cogl-texture.h',
|
||||||
'cogl-texture-2d.h',
|
'cogl-texture-2d.h',
|
||||||
@ -126,6 +127,7 @@ cogl_nonintrospected_headers = [
|
|||||||
'cogl-sub-texture.h',
|
'cogl-sub-texture.h',
|
||||||
'cogl-atlas-texture.h',
|
'cogl-atlas-texture.h',
|
||||||
'cogl-meta-texture.h',
|
'cogl-meta-texture.h',
|
||||||
|
'cogl-multi-plane-texture.h',
|
||||||
'cogl-primitive-texture.h',
|
'cogl-primitive-texture.h',
|
||||||
'cogl-depth-state.h',
|
'cogl-depth-state.h',
|
||||||
'cogl-buffer.h',
|
'cogl-buffer.h',
|
||||||
@ -252,10 +254,11 @@ cogl_sources = [
|
|||||||
'cogl-bitmap-pixbuf.c',
|
'cogl-bitmap-pixbuf.c',
|
||||||
'cogl-clip-stack.h',
|
'cogl-clip-stack.h',
|
||||||
'cogl-clip-stack.c',
|
'cogl-clip-stack.c',
|
||||||
'cogl-feature-private.h',
|
|
||||||
'cogl-feature-private.c',
|
|
||||||
'cogl-color-private.h',
|
'cogl-color-private.h',
|
||||||
'cogl-color.c',
|
'cogl-color.c',
|
||||||
|
'cogl-pixel-format-conversion.c',
|
||||||
|
'cogl-feature-private.c',
|
||||||
|
'cogl-feature-private.h',
|
||||||
'cogl-buffer-private.h',
|
'cogl-buffer-private.h',
|
||||||
'cogl-buffer.c',
|
'cogl-buffer.c',
|
||||||
'cogl-pixel-buffer-private.h',
|
'cogl-pixel-buffer-private.h',
|
||||||
@ -325,6 +328,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',
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
ClutterActor *meta_shaped_texture_new (void);
|
ClutterActor *meta_shaped_texture_new (void);
|
||||||
void meta_shaped_texture_set_texture (MetaShapedTexture *stex,
|
void meta_shaped_texture_set_texture (MetaShapedTexture *stex,
|
||||||
CoglTexture *texture);
|
CoglMultiPlaneTexture *texture);
|
||||||
void meta_shaped_texture_set_is_y_inverted (MetaShapedTexture *stex,
|
void meta_shaped_texture_set_is_y_inverted (MetaShapedTexture *stex,
|
||||||
gboolean is_y_inverted);
|
gboolean is_y_inverted);
|
||||||
void meta_shaped_texture_set_snippet (MetaShapedTexture *stex,
|
void meta_shaped_texture_set_snippet (MetaShapedTexture *stex,
|
||||||
|
@ -89,7 +89,7 @@ struct _MetaShapedTexture
|
|||||||
|
|
||||||
MetaTextureTower *paint_tower;
|
MetaTextureTower *paint_tower;
|
||||||
|
|
||||||
CoglTexture *texture;
|
CoglMultiPlaneTexture *texture;
|
||||||
CoglTexture *mask_texture;
|
CoglTexture *mask_texture;
|
||||||
CoglSnippet *snippet;
|
CoglSnippet *snippet;
|
||||||
|
|
||||||
@ -97,6 +97,8 @@ struct _MetaShapedTexture
|
|||||||
CoglPipeline *masked_pipeline;
|
CoglPipeline *masked_pipeline;
|
||||||
CoglPipeline *unblended_pipeline;
|
CoglPipeline *unblended_pipeline;
|
||||||
|
|
||||||
|
CoglPixelFormatConversion *pixel_format_conversion;
|
||||||
|
|
||||||
gboolean is_y_inverted;
|
gboolean is_y_inverted;
|
||||||
|
|
||||||
/* The region containing only fully opaque pixels */
|
/* The region containing only fully opaque pixels */
|
||||||
@ -277,9 +279,11 @@ set_clip_region (MetaShapedTexture *stex,
|
|||||||
static void
|
static void
|
||||||
meta_shaped_texture_reset_pipelines (MetaShapedTexture *stex)
|
meta_shaped_texture_reset_pipelines (MetaShapedTexture *stex)
|
||||||
{
|
{
|
||||||
g_clear_pointer (&stex->base_pipeline, cogl_object_unref);
|
g_warning ("resetting pipelines!");
|
||||||
g_clear_pointer (&stex->masked_pipeline, cogl_object_unref);
|
|
||||||
g_clear_pointer (&stex->unblended_pipeline, cogl_object_unref);
|
cogl_clear_object (&stex->base_pipeline);
|
||||||
|
cogl_clear_object (&stex->masked_pipeline);
|
||||||
|
cogl_clear_object (&stex->unblended_pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -297,7 +301,8 @@ meta_shaped_texture_dispose (GObject *object)
|
|||||||
meta_texture_tower_free (stex->paint_tower);
|
meta_texture_tower_free (stex->paint_tower);
|
||||||
stex->paint_tower = NULL;
|
stex->paint_tower = NULL;
|
||||||
|
|
||||||
g_clear_pointer (&stex->texture, cogl_object_unref);
|
cogl_clear_object (&stex->pixel_format_conversion);
|
||||||
|
cogl_clear_object (&stex->texture);
|
||||||
g_clear_pointer (&stex->opaque_region, cairo_region_destroy);
|
g_clear_pointer (&stex->opaque_region, cairo_region_destroy);
|
||||||
|
|
||||||
meta_shaped_texture_set_mask_texture (stex, NULL);
|
meta_shaped_texture_set_mask_texture (stex, NULL);
|
||||||
@ -306,7 +311,7 @@ meta_shaped_texture_dispose (GObject *object)
|
|||||||
|
|
||||||
meta_shaped_texture_reset_pipelines (stex);
|
meta_shaped_texture_reset_pipelines (stex);
|
||||||
|
|
||||||
g_clear_pointer (&stex->snippet, cogl_object_unref);
|
cogl_clear_object (&stex->snippet);
|
||||||
|
|
||||||
G_OBJECT_CLASS (meta_shaped_texture_parent_class)->dispose (object);
|
G_OBJECT_CLASS (meta_shaped_texture_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
@ -316,19 +321,26 @@ get_base_pipeline (MetaShapedTexture *stex,
|
|||||||
CoglContext *ctx)
|
CoglContext *ctx)
|
||||||
{
|
{
|
||||||
CoglPipeline *pipeline;
|
CoglPipeline *pipeline;
|
||||||
|
CoglMatrix matrix;
|
||||||
|
guint n_planes;
|
||||||
|
guint i = 0;
|
||||||
|
|
||||||
if (stex->base_pipeline)
|
if (stex->base_pipeline)
|
||||||
return stex->base_pipeline;
|
return stex->base_pipeline;
|
||||||
|
|
||||||
pipeline = cogl_pipeline_new (ctx);
|
pipeline = cogl_pipeline_new (ctx);
|
||||||
cogl_pipeline_set_layer_wrap_mode_s (pipeline, 0,
|
|
||||||
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
|
n_planes = cogl_multi_plane_texture_get_n_planes (stex->texture);
|
||||||
cogl_pipeline_set_layer_wrap_mode_t (pipeline, 0,
|
for (i = 0; i < n_planes; i++)
|
||||||
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
|
{
|
||||||
cogl_pipeline_set_layer_wrap_mode_s (pipeline, 1,
|
cogl_pipeline_set_layer_wrap_mode_s (pipeline, i,
|
||||||
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
|
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
|
||||||
cogl_pipeline_set_layer_wrap_mode_t (pipeline, 1,
|
cogl_pipeline_set_layer_wrap_mode_t (pipeline, i,
|
||||||
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
|
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
cogl_matrix_init_identity (&matrix);
|
||||||
|
|
||||||
if (!stex->is_y_inverted)
|
if (!stex->is_y_inverted)
|
||||||
{
|
{
|
||||||
CoglMatrix matrix;
|
CoglMatrix matrix;
|
||||||
@ -378,8 +390,14 @@ get_base_pipeline (MetaShapedTexture *stex,
|
|||||||
cogl_pipeline_set_layer_matrix (pipeline, 1, &matrix);
|
cogl_pipeline_set_layer_matrix (pipeline, 1, &matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < n_planes + 1; i++)
|
||||||
|
cogl_pipeline_set_layer_matrix (pipeline, i, &matrix);
|
||||||
|
|
||||||
if (stex->snippet)
|
if (stex->snippet)
|
||||||
cogl_pipeline_add_layer_snippet (pipeline, 0, stex->snippet);
|
{
|
||||||
|
for (i = 0; i < n_planes; i++)
|
||||||
|
cogl_pipeline_add_layer_snippet (pipeline, i, stex->snippet);
|
||||||
|
}
|
||||||
|
|
||||||
stex->base_pipeline = pipeline;
|
stex->base_pipeline = pipeline;
|
||||||
|
|
||||||
@ -398,12 +416,14 @@ get_masked_pipeline (MetaShapedTexture *stex,
|
|||||||
CoglContext *ctx)
|
CoglContext *ctx)
|
||||||
{
|
{
|
||||||
CoglPipeline *pipeline;
|
CoglPipeline *pipeline;
|
||||||
|
gint i, n_layers = 0;
|
||||||
|
|
||||||
if (stex->masked_pipeline)
|
if (stex->masked_pipeline)
|
||||||
return stex->masked_pipeline;
|
return stex->masked_pipeline;
|
||||||
|
|
||||||
pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
|
pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
|
||||||
cogl_pipeline_set_layer_combine (pipeline, 1,
|
n_layers = cogl_multi_plane_texture_get_n_planes (stex->texture);
|
||||||
|
cogl_pipeline_set_layer_combine (pipeline, n_layers,
|
||||||
"RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
|
"RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
@ -417,17 +437,15 @@ get_unblended_pipeline (MetaShapedTexture *stex,
|
|||||||
CoglContext *ctx)
|
CoglContext *ctx)
|
||||||
{
|
{
|
||||||
CoglPipeline *pipeline;
|
CoglPipeline *pipeline;
|
||||||
CoglColor color;
|
|
||||||
|
|
||||||
if (stex->unblended_pipeline)
|
if (stex->unblended_pipeline)
|
||||||
return stex->unblended_pipeline;
|
return stex->unblended_pipeline;
|
||||||
|
|
||||||
pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
|
pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
|
||||||
cogl_color_init_from_4ub (&color, 255, 255, 255, 255);
|
|
||||||
cogl_pipeline_set_blend (pipeline,
|
cogl_pipeline_set_blend (pipeline,
|
||||||
"RGBA = ADD (SRC_COLOR, 0)",
|
"RGBA = ADD (SRC_COLOR, 0)",
|
||||||
NULL);
|
NULL);
|
||||||
cogl_pipeline_set_color (pipeline, &color);
|
cogl_pipeline_set_color4ub (pipeline, 255, 255, 255, 255);
|
||||||
|
|
||||||
stex->unblended_pipeline = pipeline;
|
stex->unblended_pipeline = pipeline;
|
||||||
|
|
||||||
@ -507,23 +525,46 @@ paint_clipped_rectangle (MetaShapedTexture *stex,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_cogl_texture (MetaShapedTexture *stex,
|
check_texture_color_format (MetaShapedTexture *stex,
|
||||||
CoglTexture *cogl_tex)
|
CoglMultiPlaneTexture *texture)
|
||||||
|
{
|
||||||
|
CoglPixelFormat format = cogl_multi_plane_texture_get_format (texture);
|
||||||
|
guint n_layers = cogl_pipeline_get_n_layers (stex->base_pipeline);
|
||||||
|
|
||||||
|
if (stex->pixel_format_conversion != NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cogl_clear_object (&stex->pixel_format_conversion);
|
||||||
|
stex->pixel_format_conversion = cogl_pixel_format_conversion_new (format);
|
||||||
|
|
||||||
|
/* Check if a snippet is actually necessary */
|
||||||
|
if (stex->pixel_format_conversion == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* XXX disable for now, our changes are still incompatible with texturetower*/
|
||||||
|
/* meta_shaped_texture_set_create_mipmaps (stex, FALSE); */
|
||||||
|
|
||||||
|
cogl_pixel_format_conversion_attach_to_pipeline (stex->pixel_format_conversion,
|
||||||
|
stex->base_pipeline,
|
||||||
|
n_layers - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_planar_texture (MetaShapedTexture *stex,
|
||||||
|
CoglMultiPlaneTexture *planar_tex)
|
||||||
{
|
{
|
||||||
int width, height;
|
int width, height;
|
||||||
|
|
||||||
g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
|
g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
|
||||||
|
|
||||||
if (stex->texture)
|
cogl_clear_object (&stex->texture);
|
||||||
cogl_object_unref (stex->texture);
|
stex->texture = planar_tex;
|
||||||
|
|
||||||
stex->texture = cogl_tex;
|
if (planar_tex != NULL)
|
||||||
|
|
||||||
if (cogl_tex != NULL)
|
|
||||||
{
|
{
|
||||||
cogl_object_ref (cogl_tex);
|
cogl_object_ref (planar_tex);
|
||||||
width = cogl_texture_get_width (COGL_TEXTURE (cogl_tex));
|
width = cogl_multi_plane_texture_get_width (planar_tex);
|
||||||
height = cogl_texture_get_height (COGL_TEXTURE (cogl_tex));
|
height = cogl_multi_plane_texture_get_height (planar_tex);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -539,13 +580,22 @@ set_cogl_texture (MetaShapedTexture *stex,
|
|||||||
update_size (stex);
|
update_size (stex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if we need to do color conversion to RGBA */
|
||||||
|
if (planar_tex != NULL && stex->base_pipeline != NULL)
|
||||||
|
{
|
||||||
|
check_texture_color_format (stex, planar_tex);
|
||||||
|
}
|
||||||
|
|
||||||
/* NB: We don't queue a redraw of the actor here because we don't
|
/* NB: We don't queue a redraw of the actor here because we don't
|
||||||
* know how much of the buffer has changed with respect to the
|
* know how much of the buffer has changed with respect to the
|
||||||
* previous buffer. We only queue a redraw in response to surface
|
* previous buffer. We only queue a redraw in response to surface
|
||||||
* damage. */
|
* damage. */
|
||||||
|
|
||||||
|
/* if (FALSE) */
|
||||||
if (stex->create_mipmaps)
|
if (stex->create_mipmaps)
|
||||||
meta_texture_tower_set_base_texture (stex->paint_tower, cogl_tex);
|
{
|
||||||
|
meta_texture_tower_set_base_texture (stex->paint_tower, planar_tex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -563,10 +613,10 @@ texture_is_idle_and_not_mipmapped (gpointer user_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_paint (MetaShapedTexture *stex,
|
do_paint (MetaShapedTexture *stex,
|
||||||
CoglFramebuffer *fb,
|
CoglFramebuffer *fb,
|
||||||
CoglTexture *paint_tex,
|
CoglMultiPlaneTexture *paint_tex,
|
||||||
cairo_region_t *clip_region)
|
cairo_region_t *clip_region)
|
||||||
{
|
{
|
||||||
double tex_scale;
|
double tex_scale;
|
||||||
int dst_width, dst_height;
|
int dst_width, dst_height;
|
||||||
@ -579,8 +629,12 @@ do_paint (MetaShapedTexture *stex,
|
|||||||
CoglContext *ctx;
|
CoglContext *ctx;
|
||||||
ClutterActorBox alloc;
|
ClutterActorBox alloc;
|
||||||
CoglPipelineFilter filter;
|
CoglPipelineFilter filter;
|
||||||
|
guint n_planes;
|
||||||
|
|
||||||
clutter_actor_get_scale (CLUTTER_ACTOR (stex), &tex_scale, NULL);
|
clutter_actor_get_scale (CLUTTER_ACTOR (stex), &tex_scale, NULL);
|
||||||
|
|
||||||
|
n_planes = cogl_multi_plane_texture_get_n_planes (paint_tex);
|
||||||
|
|
||||||
ensure_size_valid (stex);
|
ensure_size_valid (stex);
|
||||||
dst_width = stex->dst_width;
|
dst_width = stex->dst_width;
|
||||||
|
|
||||||
@ -686,8 +740,15 @@ do_paint (MetaShapedTexture *stex,
|
|||||||
if (!cairo_region_is_empty (region))
|
if (!cairo_region_is_empty (region))
|
||||||
{
|
{
|
||||||
opaque_pipeline = get_unblended_pipeline (stex, ctx);
|
opaque_pipeline = get_unblended_pipeline (stex, ctx);
|
||||||
cogl_pipeline_set_layer_texture (opaque_pipeline, 0, paint_tex);
|
|
||||||
cogl_pipeline_set_layer_filters (opaque_pipeline, 0, filter, filter);
|
for (i = 0; i < n_planes; i++)
|
||||||
|
{
|
||||||
|
CoglTexture *plane = cogl_multi_plane_texture_get_plane (paint_tex, i);
|
||||||
|
|
||||||
|
|
||||||
|
cogl_pipeline_set_layer_texture (opaque_pipeline, i, plane);
|
||||||
|
cogl_pipeline_set_layer_filters (opaque_pipeline, i, filter, filter);
|
||||||
|
}
|
||||||
|
|
||||||
n_rects = cairo_region_num_rectangles (region);
|
n_rects = cairo_region_num_rectangles (region);
|
||||||
for (i = 0; i < n_rects; i++)
|
for (i = 0; i < n_rects; i++)
|
||||||
@ -718,6 +779,7 @@ do_paint (MetaShapedTexture *stex,
|
|||||||
if (!blended_tex_region || !cairo_region_is_empty (blended_tex_region))
|
if (!blended_tex_region || !cairo_region_is_empty (blended_tex_region))
|
||||||
{
|
{
|
||||||
CoglPipeline *blended_pipeline;
|
CoglPipeline *blended_pipeline;
|
||||||
|
guint i;
|
||||||
|
|
||||||
if (stex->mask_texture == NULL)
|
if (stex->mask_texture == NULL)
|
||||||
{
|
{
|
||||||
@ -726,16 +788,21 @@ do_paint (MetaShapedTexture *stex,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
blended_pipeline = get_masked_pipeline (stex, ctx);
|
blended_pipeline = get_masked_pipeline (stex, ctx);
|
||||||
cogl_pipeline_set_layer_texture (blended_pipeline, 1, stex->mask_texture);
|
cogl_pipeline_set_layer_texture (blended_pipeline, n_planes, stex->mask_texture);
|
||||||
cogl_pipeline_set_layer_filters (blended_pipeline, 1, filter, filter);
|
cogl_pipeline_set_layer_filters (blended_pipeline, n_planes, filter, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
cogl_pipeline_set_layer_texture (blended_pipeline, 0, paint_tex);
|
for (i = 0; i < n_planes; i++)
|
||||||
cogl_pipeline_set_layer_filters (blended_pipeline, 0, filter, filter);
|
{
|
||||||
|
CoglTexture *plane = cogl_multi_plane_texture_get_plane (paint_tex, i);
|
||||||
|
/* g_warning ("Blended pipeline: adding layer %d, %p", i, plane); */
|
||||||
|
|
||||||
CoglColor color;
|
cogl_pipeline_set_layer_texture (blended_pipeline, i, plane);
|
||||||
cogl_color_init_from_4ub (&color, opacity, opacity, opacity, opacity);
|
cogl_pipeline_set_layer_filters (blended_pipeline, i, filter, filter);
|
||||||
cogl_pipeline_set_color (blended_pipeline, &color);
|
}
|
||||||
|
|
||||||
|
cogl_pipeline_set_color4ub (blended_pipeline,
|
||||||
|
opacity, opacity, opacity, opacity);
|
||||||
|
|
||||||
if (blended_tex_region)
|
if (blended_tex_region)
|
||||||
{
|
{
|
||||||
@ -778,7 +845,7 @@ static void
|
|||||||
meta_shaped_texture_paint (ClutterActor *actor)
|
meta_shaped_texture_paint (ClutterActor *actor)
|
||||||
{
|
{
|
||||||
MetaShapedTexture *stex = META_SHAPED_TEXTURE (actor);
|
MetaShapedTexture *stex = META_SHAPED_TEXTURE (actor);
|
||||||
CoglTexture *paint_tex;
|
CoglMultiPlaneTexture *paint_tex;
|
||||||
CoglFramebuffer *fb;
|
CoglFramebuffer *fb;
|
||||||
|
|
||||||
if (!stex->texture)
|
if (!stex->texture)
|
||||||
@ -806,6 +873,7 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
|||||||
* support for TFP textures will result in fallbacks to XGetImage.
|
* support for TFP textures will result in fallbacks to XGetImage.
|
||||||
*/
|
*/
|
||||||
if (stex->create_mipmaps)
|
if (stex->create_mipmaps)
|
||||||
|
/* if (FALSE) */
|
||||||
{
|
{
|
||||||
int64_t now = g_get_monotonic_time ();
|
int64_t now = g_get_monotonic_time ();
|
||||||
int64_t age = now - stex->last_invalidation;
|
int64_t age = now - stex->last_invalidation;
|
||||||
@ -833,11 +901,11 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
paint_tex = COGL_TEXTURE (stex->texture);
|
paint_tex = stex->texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cogl_texture_get_width (paint_tex) == 0 ||
|
if (cogl_multi_plane_texture_get_width (paint_tex) == 0 ||
|
||||||
cogl_texture_get_height (paint_tex) == 0)
|
cogl_multi_plane_texture_get_height (paint_tex) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fb = cogl_get_draw_framebuffer ();
|
fb = cogl_get_draw_framebuffer ();
|
||||||
@ -911,7 +979,7 @@ meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex,
|
|||||||
|
|
||||||
if (create_mipmaps != stex->create_mipmaps)
|
if (create_mipmaps != stex->create_mipmaps)
|
||||||
{
|
{
|
||||||
CoglTexture *base_texture;
|
CoglMultiPlaneTexture *base_texture;
|
||||||
stex->create_mipmaps = create_mipmaps;
|
stex->create_mipmaps = create_mipmaps;
|
||||||
base_texture = create_mipmaps ? stex->texture : NULL;
|
base_texture = create_mipmaps ? stex->texture : NULL;
|
||||||
meta_texture_tower_set_base_texture (stex->paint_tower, base_texture);
|
meta_texture_tower_set_base_texture (stex->paint_tower, base_texture);
|
||||||
@ -1094,15 +1162,15 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
|
|||||||
/**
|
/**
|
||||||
* meta_shaped_texture_set_texture:
|
* meta_shaped_texture_set_texture:
|
||||||
* @stex: The #MetaShapedTexture
|
* @stex: The #MetaShapedTexture
|
||||||
* @pixmap: The #CoglTexture to display
|
* @pixmap: The #CoglMultiPlaneTexture to display
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
meta_shaped_texture_set_texture (MetaShapedTexture *stex,
|
meta_shaped_texture_set_texture (MetaShapedTexture *stex,
|
||||||
CoglTexture *texture)
|
CoglMultiPlaneTexture *texture)
|
||||||
{
|
{
|
||||||
g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
|
g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
|
||||||
|
|
||||||
set_cogl_texture (stex, texture);
|
set_planar_texture (stex, texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1132,7 +1200,7 @@ meta_shaped_texture_set_snippet (MetaShapedTexture *stex,
|
|||||||
|
|
||||||
meta_shaped_texture_reset_pipelines (stex);
|
meta_shaped_texture_reset_pipelines (stex);
|
||||||
|
|
||||||
g_clear_pointer (&stex->snippet, cogl_object_unref);
|
cogl_clear_object (&stex->snippet);
|
||||||
if (snippet)
|
if (snippet)
|
||||||
stex->snippet = cogl_object_ref (snippet);
|
stex->snippet = cogl_object_ref (snippet);
|
||||||
}
|
}
|
||||||
@ -1143,11 +1211,12 @@ meta_shaped_texture_set_snippet (MetaShapedTexture *stex,
|
|||||||
*
|
*
|
||||||
* Returns: (transfer none): the unshaped texture
|
* Returns: (transfer none): the unshaped texture
|
||||||
*/
|
*/
|
||||||
CoglTexture *
|
CoglMultiPlaneTexture *
|
||||||
meta_shaped_texture_get_texture (MetaShapedTexture *stex)
|
meta_shaped_texture_get_texture (MetaShapedTexture *stex)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), NULL);
|
g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), NULL);
|
||||||
return COGL_TEXTURE (stex->texture);
|
|
||||||
|
return stex->texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1244,7 +1313,15 @@ meta_shaped_texture_reset_viewport_dst_size (MetaShapedTexture *stex)
|
|||||||
static gboolean
|
static gboolean
|
||||||
should_get_via_offscreen (MetaShapedTexture *stex)
|
should_get_via_offscreen (MetaShapedTexture *stex)
|
||||||
{
|
{
|
||||||
if (!cogl_texture_is_get_data_supported (stex->texture))
|
CoglTexture *texture;
|
||||||
|
|
||||||
|
/* If we have more than 1 plane, we can't access the data */
|
||||||
|
if (cogl_multi_plane_texture_get_n_planes (stex->texture) > 1)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* We have only 1 plane -> access it directly */
|
||||||
|
texture = cogl_multi_plane_texture_get_plane (stex->texture, 0);
|
||||||
|
if (!cogl_texture_is_get_data_supported (texture))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
if (stex->has_viewport_src_rect || stex->has_viewport_dst_size)
|
if (stex->has_viewport_src_rect || stex->has_viewport_dst_size)
|
||||||
@ -1361,19 +1438,19 @@ get_image_via_offscreen (MetaShapedTexture *stex,
|
|||||||
* Returns: (transfer full): a new cairo surface to be freed with
|
* Returns: (transfer full): a new cairo surface to be freed with
|
||||||
* cairo_surface_destroy().
|
* cairo_surface_destroy().
|
||||||
*/
|
*/
|
||||||
|
/* XXX Still need to fix this, but apparently only used for screenshot */
|
||||||
cairo_surface_t *
|
cairo_surface_t *
|
||||||
meta_shaped_texture_get_image (MetaShapedTexture *stex,
|
meta_shaped_texture_get_image (MetaShapedTexture *stex,
|
||||||
cairo_rectangle_int_t *clip)
|
cairo_rectangle_int_t *clip)
|
||||||
{
|
{
|
||||||
cairo_rectangle_int_t *transformed_clip = NULL;
|
cairo_rectangle_int_t *transformed_clip = NULL;
|
||||||
CoglTexture *texture, *mask_texture;
|
CoglTexture *texture;
|
||||||
|
CoglTexture *mask_texture;
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface;
|
||||||
|
|
||||||
g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), NULL);
|
g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), NULL);
|
||||||
|
|
||||||
texture = COGL_TEXTURE (stex->texture);
|
if (stex->texture == NULL)
|
||||||
|
|
||||||
if (texture == NULL)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
ensure_size_valid (stex);
|
ensure_size_valid (stex);
|
||||||
@ -1406,6 +1483,9 @@ meta_shaped_texture_get_image (MetaShapedTexture *stex,
|
|||||||
if (should_get_via_offscreen (stex))
|
if (should_get_via_offscreen (stex))
|
||||||
return get_image_via_offscreen (stex, transformed_clip);
|
return get_image_via_offscreen (stex, transformed_clip);
|
||||||
|
|
||||||
|
/* We know that we only have 1 plane at this point */
|
||||||
|
texture = cogl_multi_plane_texture_get_plane (stex->texture, 0);
|
||||||
|
|
||||||
if (transformed_clip)
|
if (transformed_clip)
|
||||||
texture = cogl_texture_new_from_sub_texture (texture,
|
texture = cogl_texture_new_from_sub_texture (texture,
|
||||||
transformed_clip->x,
|
transformed_clip->x,
|
||||||
|
@ -45,7 +45,7 @@ struct _MetaSurfaceActorX11
|
|||||||
|
|
||||||
MetaDisplay *display;
|
MetaDisplay *display;
|
||||||
|
|
||||||
CoglTexture *texture;
|
CoglMultiPlaneTexture *texture;
|
||||||
Pixmap pixmap;
|
Pixmap pixmap;
|
||||||
Damage damage;
|
Damage damage;
|
||||||
|
|
||||||
@ -129,8 +129,9 @@ set_pixmap (MetaSurfaceActorX11 *self,
|
|||||||
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 (texture))))
|
||||||
g_warning ("NOTE: Not using GLX TFP!\n");
|
g_warning ("NOTE: Not using GLX TFP!\n");
|
||||||
|
|
||||||
self->texture = texture;
|
/* FIXME: we need to find out the format here */
|
||||||
meta_shaped_texture_set_texture (stex, texture);
|
self->texture = cogl_multi_plane_texture_new_single_plane (COGL_PIXEL_FORMAT_ANY, texture);
|
||||||
|
meta_shaped_texture_set_texture (stex, self->texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -187,6 +188,7 @@ meta_surface_actor_x11_process_damage (MetaSurfaceActor *actor,
|
|||||||
int x, int y, int width, int height)
|
int x, int y, int width, int height)
|
||||||
{
|
{
|
||||||
MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor);
|
MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor);
|
||||||
|
CoglTexture *texture;
|
||||||
|
|
||||||
self->received_damage = TRUE;
|
self->received_damage = TRUE;
|
||||||
|
|
||||||
@ -210,7 +212,8 @@ meta_surface_actor_x11_process_damage (MetaSurfaceActor *actor,
|
|||||||
if (!is_visible (self))
|
if (!is_visible (self))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cogl_texture_pixmap_x11_update_area (COGL_TEXTURE_PIXMAP_X11 (self->texture),
|
texture = cogl_multi_plane_texture_get_plane (self->texture, 0);
|
||||||
|
cogl_texture_pixmap_x11_update_area (COGL_TEXTURE_PIXMAP_X11 (texture),
|
||||||
x, y, width, height);
|
x, y, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,7 +325,8 @@ gboolean
|
|||||||
meta_surface_actor_is_argb32 (MetaSurfaceActor *self)
|
meta_surface_actor_is_argb32 (MetaSurfaceActor *self)
|
||||||
{
|
{
|
||||||
MetaShapedTexture *stex = meta_surface_actor_get_texture (self);
|
MetaShapedTexture *stex = meta_surface_actor_get_texture (self);
|
||||||
CoglTexture *texture = meta_shaped_texture_get_texture (stex);
|
CoglMultiPlaneTexture *mtex = meta_shaped_texture_get_texture (stex);
|
||||||
|
CoglTexture *texture;
|
||||||
|
|
||||||
/* If we don't have a texture, like during initialization, assume
|
/* If we don't have a texture, like during initialization, assume
|
||||||
* that we're ARGB32.
|
* that we're ARGB32.
|
||||||
@ -335,9 +336,14 @@ meta_surface_actor_is_argb32 (MetaSurfaceActor *self)
|
|||||||
* place. This prevents us from continually redirecting and
|
* place. This prevents us from continually redirecting and
|
||||||
* unredirecting on every paint.
|
* unredirecting on every paint.
|
||||||
*/
|
*/
|
||||||
if (!texture)
|
if (!mtex)
|
||||||
return !meta_surface_actor_is_unredirected (self);
|
return !meta_surface_actor_is_unredirected (self);
|
||||||
|
|
||||||
|
/* Are we dealing with multiple planes? Then it can't be argb32 either */
|
||||||
|
if (cogl_multi_plane_texture_get_n_planes (mtex) != 1)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
texture = cogl_multi_plane_texture_get_plane (mtex, 0);
|
||||||
switch (cogl_texture_get_components (texture))
|
switch (cogl_texture_get_components (texture))
|
||||||
{
|
{
|
||||||
case COGL_TEXTURE_COMPONENTS_A:
|
case COGL_TEXTURE_COMPONENTS_A:
|
||||||
|
@ -59,8 +59,8 @@ typedef struct
|
|||||||
struct _MetaTextureTower
|
struct _MetaTextureTower
|
||||||
{
|
{
|
||||||
int n_levels;
|
int n_levels;
|
||||||
CoglTexture *textures[MAX_TEXTURE_LEVELS];
|
CoglMultiPlaneTexture *textures[MAX_TEXTURE_LEVELS];
|
||||||
CoglOffscreen *fbos[MAX_TEXTURE_LEVELS];
|
GList *fbos[MAX_TEXTURE_LEVELS];
|
||||||
Box invalid[MAX_TEXTURE_LEVELS];
|
Box invalid[MAX_TEXTURE_LEVELS];
|
||||||
CoglPipeline *pipeline_template;
|
CoglPipeline *pipeline_template;
|
||||||
};
|
};
|
||||||
@ -113,8 +113,8 @@ meta_texture_tower_free (MetaTextureTower *tower)
|
|||||||
* unset or until the tower is freed.
|
* unset or until the tower is freed.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
meta_texture_tower_set_base_texture (MetaTextureTower *tower,
|
meta_texture_tower_set_base_texture (MetaTextureTower *tower,
|
||||||
CoglTexture *texture)
|
CoglMultiPlaneTexture *texture)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -127,22 +127,14 @@ meta_texture_tower_set_base_texture (MetaTextureTower *tower,
|
|||||||
{
|
{
|
||||||
for (i = 1; i < tower->n_levels; i++)
|
for (i = 1; i < tower->n_levels; i++)
|
||||||
{
|
{
|
||||||
if (tower->textures[i] != NULL)
|
cogl_clear_object (&tower->textures[i]);
|
||||||
{
|
|
||||||
cogl_object_unref (tower->textures[i]);
|
|
||||||
tower->textures[i] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tower->fbos[i] != NULL)
|
g_list_free_full (tower->fbos[i], cogl_object_unref);
|
||||||
{
|
tower->fbos[i] = NULL;
|
||||||
cogl_object_unref (tower->fbos[i]);
|
|
||||||
tower->fbos[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cogl_object_unref (tower->textures[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cogl_clear_object (&tower->textures[0]);
|
||||||
tower->textures[0] = texture;
|
tower->textures[0] = texture;
|
||||||
|
|
||||||
if (tower->textures[0] != NULL)
|
if (tower->textures[0] != NULL)
|
||||||
@ -151,8 +143,8 @@ meta_texture_tower_set_base_texture (MetaTextureTower *tower,
|
|||||||
|
|
||||||
cogl_object_ref (tower->textures[0]);
|
cogl_object_ref (tower->textures[0]);
|
||||||
|
|
||||||
width = cogl_texture_get_width (tower->textures[0]);
|
width = cogl_multi_plane_texture_get_width (tower->textures[0]);
|
||||||
height = cogl_texture_get_height (tower->textures[0]);
|
height = cogl_multi_plane_texture_get_height (tower->textures[0]);
|
||||||
|
|
||||||
tower->n_levels = 1 + MAX ((int)(M_LOG2E * log (width)), (int)(M_LOG2E * log (height)));
|
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);
|
tower->n_levels = MIN(tower->n_levels, MAX_TEXTURE_LEVELS);
|
||||||
@ -193,8 +185,8 @@ meta_texture_tower_update_area (MetaTextureTower *tower,
|
|||||||
if (tower->textures[0] == NULL)
|
if (tower->textures[0] == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
texture_width = cogl_texture_get_width (tower->textures[0]);
|
texture_width = cogl_multi_plane_texture_get_width (tower->textures[0]);
|
||||||
texture_height = cogl_texture_get_height (tower->textures[0]);
|
texture_height = cogl_multi_plane_texture_get_height (tower->textures[0]);
|
||||||
|
|
||||||
invalid.x1 = x;
|
invalid.x1 = x;
|
||||||
invalid.y1 = y;
|
invalid.y1 = y;
|
||||||
@ -358,23 +350,28 @@ texture_tower_create_texture (MetaTextureTower *tower,
|
|||||||
int width,
|
int width,
|
||||||
int height)
|
int height)
|
||||||
{
|
{
|
||||||
if ((!is_power_of_two (width) || !is_power_of_two (height)) &&
|
CoglMultiPlaneTexture *base_tex = tower->textures[0];
|
||||||
meta_texture_rectangle_check (tower->textures[level - 1]))
|
GPtrArray *planes;
|
||||||
{
|
guint n_planes, i;
|
||||||
ClutterBackend *backend = clutter_get_default_backend ();
|
|
||||||
CoglContext *context = clutter_backend_get_cogl_context (backend);
|
|
||||||
CoglTextureRectangle *texture_rectangle;
|
|
||||||
|
|
||||||
texture_rectangle = cogl_texture_rectangle_new_with_size (context, width, height);
|
n_planes = cogl_multi_plane_texture_get_n_planes (base_tex);
|
||||||
tower->textures[level] = COGL_TEXTURE (texture_rectangle);
|
planes = g_ptr_array_new_full (n_planes, cogl_object_unref);
|
||||||
}
|
|
||||||
else
|
for (i = 0; i < n_planes; i++)
|
||||||
{
|
{
|
||||||
tower->textures[level] = cogl_texture_new_with_size (width, height,
|
CoglTexture *texture;
|
||||||
COGL_TEXTURE_NO_AUTO_MIPMAP,
|
|
||||||
TEXTURE_FORMAT);
|
texture = cogl_texture_new_with_size (width, height,
|
||||||
|
COGL_TEXTURE_NO_AUTO_MIPMAP,
|
||||||
|
TEXTURE_FORMAT);
|
||||||
|
g_ptr_array_add (planes, texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tower->textures[level] = cogl_multi_plane_texture_new (
|
||||||
|
cogl_multi_plane_texture_get_format (base_tex),
|
||||||
|
(CoglTexture **) g_ptr_array_free (planes, FALSE),
|
||||||
|
n_planes);
|
||||||
|
|
||||||
tower->invalid[level].x1 = 0;
|
tower->invalid[level].x1 = 0;
|
||||||
tower->invalid[level].y1 = 0;
|
tower->invalid[level].y1 = 0;
|
||||||
tower->invalid[level].x2 = width;
|
tower->invalid[level].x2 = width;
|
||||||
@ -385,51 +382,69 @@ static void
|
|||||||
texture_tower_revalidate (MetaTextureTower *tower,
|
texture_tower_revalidate (MetaTextureTower *tower,
|
||||||
int level)
|
int level)
|
||||||
{
|
{
|
||||||
CoglTexture *source_texture = tower->textures[level - 1];
|
CoglMultiPlaneTexture *src_tex = tower->textures[level - 1];
|
||||||
int source_texture_width = cogl_texture_get_width (source_texture);
|
int src_width = cogl_multi_plane_texture_get_width (src_tex);
|
||||||
int source_texture_height = cogl_texture_get_height (source_texture);
|
int src_height = cogl_multi_plane_texture_get_height (src_tex);
|
||||||
CoglTexture *dest_texture = tower->textures[level];
|
guint src_tex_n_planes = cogl_multi_plane_texture_get_n_planes (src_tex);
|
||||||
int dest_texture_width = cogl_texture_get_width (dest_texture);
|
CoglMultiPlaneTexture *dest_tex = tower->textures[level];
|
||||||
int dest_texture_height = cogl_texture_get_height (dest_texture);
|
int dest_width = cogl_multi_plane_texture_get_width (dest_tex);
|
||||||
Box *invalid = &tower->invalid[level];
|
int dest_height = cogl_multi_plane_texture_get_height (dest_tex);
|
||||||
CoglFramebuffer *fb;
|
guint i;
|
||||||
CoglError *catch_error = NULL;
|
|
||||||
CoglPipeline *pipeline;
|
|
||||||
|
|
||||||
if (tower->fbos[level] == NULL)
|
|
||||||
tower->fbos[level] = cogl_offscreen_new_with_texture (dest_texture);
|
|
||||||
|
|
||||||
fb = COGL_FRAMEBUFFER (tower->fbos[level]);
|
/* FIXME: cogl_offscreen_texture_new_with_texture doesn't work for
|
||||||
|
* multi-plane textures, so we have to make an FBO for each layer */
|
||||||
if (!cogl_framebuffer_allocate (fb, &catch_error))
|
for (i = 0; i < src_tex_n_planes; i++)
|
||||||
{
|
{
|
||||||
cogl_error_free (catch_error);
|
Box *invalid = &tower->invalid[level];
|
||||||
return;
|
CoglTexture *src_plane, *dest_plane;
|
||||||
|
CoglFramebuffer *fb;
|
||||||
|
CoglError *catch_error = NULL;
|
||||||
|
CoglPipeline *pipeline;
|
||||||
|
|
||||||
|
src_plane = cogl_multi_plane_texture_get_plane (src_tex, i);
|
||||||
|
dest_plane = cogl_multi_plane_texture_get_plane (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_plane));
|
||||||
|
tower->fbos[level] = g_list_append (tower->fbos[level], fb);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cogl_framebuffer_allocate (fb, &catch_error))
|
||||||
|
{
|
||||||
|
cogl_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_plane);
|
||||||
|
|
||||||
|
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].x1 = tower->invalid[level].x2 = 0;
|
||||||
tower->invalid[level].y1 = tower->invalid[level].y2 = 0;
|
tower->invalid[level].y1 = tower->invalid[level].y2 = 0;
|
||||||
}
|
}
|
||||||
@ -447,7 +462,7 @@ texture_tower_revalidate (MetaTextureTower *tower,
|
|||||||
* Return value: the COGL texture handle to use for painting, or
|
* Return value: the COGL texture handle to use for painting, or
|
||||||
* %NULL if no base texture has yet been set.
|
* %NULL if no base texture has yet been set.
|
||||||
*/
|
*/
|
||||||
CoglTexture *
|
CoglMultiPlaneTexture *
|
||||||
meta_texture_tower_get_paint_texture (MetaTextureTower *tower)
|
meta_texture_tower_get_paint_texture (MetaTextureTower *tower)
|
||||||
{
|
{
|
||||||
int texture_width, texture_height;
|
int texture_width, texture_height;
|
||||||
@ -458,8 +473,8 @@ meta_texture_tower_get_paint_texture (MetaTextureTower *tower)
|
|||||||
if (tower->textures[0] == NULL)
|
if (tower->textures[0] == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
texture_width = cogl_texture_get_width (tower->textures[0]);
|
texture_width = cogl_multi_plane_texture_get_width (tower->textures[0]);
|
||||||
texture_height = cogl_texture_get_height (tower->textures[0]);
|
texture_height = cogl_multi_plane_texture_get_height (tower->textures[0]);
|
||||||
|
|
||||||
level = get_paint_level(texture_width, texture_height);
|
level = get_paint_level(texture_width, texture_height);
|
||||||
if (level < 0) /* singular paint matrix, scaled to nothing */
|
if (level < 0) /* singular paint matrix, scaled to nothing */
|
||||||
|
@ -53,14 +53,14 @@ typedef struct _MetaTextureTower MetaTextureTower;
|
|||||||
|
|
||||||
MetaTextureTower *meta_texture_tower_new (void);
|
MetaTextureTower *meta_texture_tower_new (void);
|
||||||
void meta_texture_tower_free (MetaTextureTower *tower);
|
void meta_texture_tower_free (MetaTextureTower *tower);
|
||||||
void meta_texture_tower_set_base_texture (MetaTextureTower *tower,
|
void meta_texture_tower_set_base_texture (MetaTextureTower *tower,
|
||||||
CoglTexture *texture);
|
CoglMultiPlaneTexture *texture);
|
||||||
void meta_texture_tower_update_area (MetaTextureTower *tower,
|
void meta_texture_tower_update_area (MetaTextureTower *tower,
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y,
|
||||||
int width,
|
int width,
|
||||||
int height);
|
int height);
|
||||||
CoglTexture *meta_texture_tower_get_paint_texture (MetaTextureTower *tower);
|
CoglMultiPlaneTexture *meta_texture_tower_get_paint_texture (MetaTextureTower *tower);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
@ -1503,10 +1503,12 @@ build_and_scan_frame_mask (MetaWindowActor *self,
|
|||||||
guchar *mask_data;
|
guchar *mask_data;
|
||||||
guint tex_width, tex_height;
|
guint tex_width, tex_height;
|
||||||
MetaShapedTexture *stex;
|
MetaShapedTexture *stex;
|
||||||
CoglTexture *paint_tex, *mask_texture;
|
CoglMultiPlaneTexture *paint_tex;
|
||||||
|
CoglTexture *mask_texture;
|
||||||
int stride;
|
int stride;
|
||||||
cairo_t *cr;
|
cairo_t *cr;
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface;
|
||||||
|
CoglError *error = NULL;
|
||||||
|
|
||||||
stex = meta_surface_actor_get_texture (priv->surface);
|
stex = meta_surface_actor_get_texture (priv->surface);
|
||||||
g_return_if_fail (stex);
|
g_return_if_fail (stex);
|
||||||
@ -1517,8 +1519,8 @@ build_and_scan_frame_mask (MetaWindowActor *self,
|
|||||||
if (paint_tex == NULL)
|
if (paint_tex == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tex_width = cogl_texture_get_width (paint_tex);
|
tex_width = cogl_multi_plane_texture_get_width (paint_tex);
|
||||||
tex_height = cogl_texture_get_height (paint_tex);
|
tex_height = cogl_multi_plane_texture_get_height (paint_tex);
|
||||||
|
|
||||||
stride = cairo_format_stride_for_width (CAIRO_FORMAT_A8, tex_width);
|
stride = cairo_format_stride_for_width (CAIRO_FORMAT_A8, tex_width);
|
||||||
|
|
||||||
@ -1559,31 +1561,14 @@ build_and_scan_frame_mask (MetaWindowActor *self,
|
|||||||
cairo_destroy (cr);
|
cairo_destroy (cr);
|
||||||
cairo_surface_destroy (surface);
|
cairo_surface_destroy (surface);
|
||||||
|
|
||||||
if (meta_texture_rectangle_check (paint_tex))
|
mask_texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (ctx, tex_width, tex_height,
|
||||||
{
|
COGL_PIXEL_FORMAT_A_8,
|
||||||
mask_texture = COGL_TEXTURE (cogl_texture_rectangle_new_with_size (ctx, tex_width, tex_height));
|
stride, mask_data, &error));
|
||||||
cogl_texture_set_components (mask_texture, COGL_TEXTURE_COMPONENTS_A);
|
|
||||||
cogl_texture_set_region (mask_texture,
|
|
||||||
0, 0, /* src_x/y */
|
|
||||||
0, 0, /* dst_x/y */
|
|
||||||
tex_width, tex_height, /* dst_width/height */
|
|
||||||
tex_width, tex_height, /* width/height */
|
|
||||||
COGL_PIXEL_FORMAT_A_8,
|
|
||||||
stride, mask_data);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CoglError *error = NULL;
|
|
||||||
|
|
||||||
mask_texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (ctx, tex_width, tex_height,
|
if (error)
|
||||||
COGL_PIXEL_FORMAT_A_8,
|
{
|
||||||
stride, mask_data, &error));
|
g_warning ("Failed to allocate mask texture: %s", error->message);
|
||||||
|
cogl_error_free (error);
|
||||||
if (error)
|
|
||||||
{
|
|
||||||
g_warning ("Failed to allocate mask texture: %s", error->message);
|
|
||||||
cogl_error_free (error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_shaped_texture_set_mask_texture (stex, mask_texture);
|
meta_shaped_texture_set_mask_texture (stex, mask_texture);
|
||||||
|
@ -52,7 +52,7 @@ gboolean meta_shaped_texture_update_area (MetaShapedTexture *stex,
|
|||||||
int height);
|
int height);
|
||||||
|
|
||||||
META_EXPORT
|
META_EXPORT
|
||||||
CoglTexture * meta_shaped_texture_get_texture (MetaShapedTexture *stex);
|
CoglMultiPlaneTexture * meta_shaped_texture_get_texture (MetaShapedTexture *stex);
|
||||||
|
|
||||||
META_EXPORT
|
META_EXPORT
|
||||||
void meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
|
void meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
|
||||||
|
@ -123,7 +123,7 @@ meta_wayland_buffer_realize (MetaWaylandBuffer *buffer)
|
|||||||
stream = meta_wayland_egl_stream_new (buffer, NULL);
|
stream = meta_wayland_egl_stream_new (buffer, NULL);
|
||||||
if (stream)
|
if (stream)
|
||||||
{
|
{
|
||||||
CoglTexture2D *texture;
|
CoglMultiPlaneTexture *texture;
|
||||||
|
|
||||||
texture = meta_wayland_egl_stream_create_texture (stream, NULL);
|
texture = meta_wayland_egl_stream_create_texture (stream, NULL);
|
||||||
if (!texture)
|
if (!texture)
|
||||||
@ -131,7 +131,7 @@ meta_wayland_buffer_realize (MetaWaylandBuffer *buffer)
|
|||||||
|
|
||||||
buffer->egl_stream.stream = stream;
|
buffer->egl_stream.stream = stream;
|
||||||
buffer->type = META_WAYLAND_BUFFER_TYPE_EGL_STREAM;
|
buffer->type = META_WAYLAND_BUFFER_TYPE_EGL_STREAM;
|
||||||
buffer->egl_stream.texture = COGL_TEXTURE (texture);
|
buffer->egl_stream.texture = texture;
|
||||||
buffer->is_y_inverted = meta_wayland_egl_stream_is_y_inverted (stream);
|
buffer->is_y_inverted = meta_wayland_egl_stream_is_y_inverted (stream);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -163,17 +163,18 @@ shm_buffer_get_cogl_pixel_format (struct wl_shm_buffer *shm_buffer,
|
|||||||
CoglTextureComponents *components_out)
|
CoglTextureComponents *components_out)
|
||||||
{
|
{
|
||||||
CoglPixelFormat format;
|
CoglPixelFormat format;
|
||||||
CoglTextureComponents components = COGL_TEXTURE_COMPONENTS_RGBA;
|
|
||||||
|
|
||||||
|
g_warning ("SHM BUFFER_FORMAT: %d", wl_shm_buffer_get_format (shm_buffer));
|
||||||
switch (wl_shm_buffer_get_format (shm_buffer))
|
switch (wl_shm_buffer_get_format (shm_buffer))
|
||||||
{
|
{
|
||||||
#if G_BYTE_ORDER == G_BIG_ENDIAN
|
#if G_BYTE_ORDER == G_BIG_ENDIAN
|
||||||
case WL_SHM_FORMAT_ARGB8888:
|
case WL_SHM_FORMAT_ARGB8888:
|
||||||
format = COGL_PIXEL_FORMAT_ARGB_8888_PRE;
|
format = COGL_PIXEL_FORMAT_ARGB_8888_PRE;
|
||||||
|
components_out[0] = COGL_TEXTURE_COMPONENTS_RGBA;
|
||||||
break;
|
break;
|
||||||
case WL_SHM_FORMAT_XRGB8888:
|
case WL_SHM_FORMAT_XRGB8888:
|
||||||
format = COGL_PIXEL_FORMAT_ARGB_8888;
|
format = COGL_PIXEL_FORMAT_ARGB_8888;
|
||||||
components = COGL_TEXTURE_COMPONENTS_RGB;
|
components_out[0] = COGL_TEXTURE_COMPONENTS_RGB;
|
||||||
break;
|
break;
|
||||||
#elif G_BYTE_ORDER == G_LITTLE_ENDIAN
|
#elif G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||||
case WL_SHM_FORMAT_ARGB8888:
|
case WL_SHM_FORMAT_ARGB8888:
|
||||||
@ -181,25 +182,59 @@ shm_buffer_get_cogl_pixel_format (struct wl_shm_buffer *shm_buffer,
|
|||||||
break;
|
break;
|
||||||
case WL_SHM_FORMAT_XRGB8888:
|
case WL_SHM_FORMAT_XRGB8888:
|
||||||
format = COGL_PIXEL_FORMAT_BGRA_8888;
|
format = COGL_PIXEL_FORMAT_BGRA_8888;
|
||||||
components = COGL_TEXTURE_COMPONENTS_RGB;
|
components_out[0] = COGL_TEXTURE_COMPONENTS_RGB;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
case WL_SHM_FORMAT_NV12:
|
||||||
|
format = COGL_PIXEL_FORMAT_NV12;
|
||||||
|
components_out[0] = COGL_TEXTURE_COMPONENTS_A;
|
||||||
|
components_out[1] = COGL_TEXTURE_COMPONENTS_RG;
|
||||||
|
break;
|
||||||
|
case WL_SHM_FORMAT_NV21:
|
||||||
|
format = COGL_PIXEL_FORMAT_NV21;
|
||||||
|
components_out[0] = COGL_TEXTURE_COMPONENTS_A;
|
||||||
|
components_out[1] = COGL_TEXTURE_COMPONENTS_RG;
|
||||||
|
break;
|
||||||
|
case WL_SHM_FORMAT_YUV422:
|
||||||
|
format = COGL_PIXEL_FORMAT_YUV422;
|
||||||
|
components_out[0] = COGL_TEXTURE_COMPONENTS_A;
|
||||||
|
components_out[1] = COGL_TEXTURE_COMPONENTS_A;
|
||||||
|
components_out[2] = COGL_TEXTURE_COMPONENTS_A;
|
||||||
|
break;
|
||||||
|
case WL_SHM_FORMAT_YVU422:
|
||||||
|
format = COGL_PIXEL_FORMAT_YVU422;
|
||||||
|
components_out[0] = COGL_TEXTURE_COMPONENTS_A;
|
||||||
|
components_out[1] = COGL_TEXTURE_COMPONENTS_A;
|
||||||
|
components_out[2] = COGL_TEXTURE_COMPONENTS_A;
|
||||||
|
break;
|
||||||
|
case WL_SHM_FORMAT_YUV444:
|
||||||
|
format = COGL_PIXEL_FORMAT_YUV444;
|
||||||
|
components_out[0] = COGL_TEXTURE_COMPONENTS_A;
|
||||||
|
components_out[1] = COGL_TEXTURE_COMPONENTS_A;
|
||||||
|
components_out[2] = COGL_TEXTURE_COMPONENTS_A;
|
||||||
|
break;
|
||||||
|
case WL_SHM_FORMAT_YVU444:
|
||||||
|
format = COGL_PIXEL_FORMAT_YVU444;
|
||||||
|
components_out[0] = COGL_TEXTURE_COMPONENTS_A;
|
||||||
|
components_out[1] = COGL_TEXTURE_COMPONENTS_A;
|
||||||
|
components_out[2] = COGL_TEXTURE_COMPONENTS_A;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
g_warn_if_reached ();
|
g_warn_if_reached ();
|
||||||
format = COGL_PIXEL_FORMAT_ARGB_8888;
|
format = COGL_PIXEL_FORMAT_ARGB_8888;
|
||||||
|
components_out[0] = COGL_TEXTURE_COMPONENTS_RGBA;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (format_out)
|
if (format_out)
|
||||||
*format_out = format;
|
*format_out = format;
|
||||||
if (components_out)
|
|
||||||
*components_out = components;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
shm_buffer_attach (MetaWaylandBuffer *buffer,
|
shm_buffer_attach (MetaWaylandBuffer *buffer,
|
||||||
CoglTexture **texture,
|
CoglMultiPlaneTexture **texture,
|
||||||
gboolean *changed_texture,
|
gboolean *changed_texture,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
MetaBackend *backend = meta_get_backend ();
|
MetaBackend *backend = meta_get_backend ();
|
||||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||||
@ -207,21 +242,27 @@ shm_buffer_attach (MetaWaylandBuffer *buffer,
|
|||||||
struct wl_shm_buffer *shm_buffer;
|
struct wl_shm_buffer *shm_buffer;
|
||||||
int stride, width, height;
|
int stride, width, height;
|
||||||
CoglPixelFormat format;
|
CoglPixelFormat format;
|
||||||
CoglTextureComponents components;
|
CoglTextureComponents components[3];
|
||||||
CoglBitmap *bitmap;
|
guint i, n_planes;
|
||||||
CoglTexture *new_texture;
|
guint h_factors[3], v_factors[3];
|
||||||
|
gsize offset = 0;
|
||||||
|
guint8 *data;
|
||||||
|
GPtrArray *bitmaps;
|
||||||
|
|
||||||
|
/* Query the necessary parameters */
|
||||||
shm_buffer = wl_shm_buffer_get (buffer->resource);
|
shm_buffer = wl_shm_buffer_get (buffer->resource);
|
||||||
stride = wl_shm_buffer_get_stride (shm_buffer);
|
stride = wl_shm_buffer_get_stride (shm_buffer);
|
||||||
width = wl_shm_buffer_get_width (shm_buffer);
|
width = wl_shm_buffer_get_width (shm_buffer);
|
||||||
height = wl_shm_buffer_get_height (shm_buffer);
|
height = wl_shm_buffer_get_height (shm_buffer);
|
||||||
shm_buffer_get_cogl_pixel_format (shm_buffer, &format, &components);
|
shm_buffer_get_cogl_pixel_format (shm_buffer, &format, components);
|
||||||
|
n_planes = cogl_pixel_format_get_n_planes (format);
|
||||||
|
cogl_pixel_format_get_subsampling_factors (format, h_factors, v_factors);
|
||||||
|
|
||||||
if (*texture &&
|
if (*texture &&
|
||||||
cogl_texture_get_width (*texture) == width &&
|
cogl_multi_plane_texture_get_width (*texture) == width &&
|
||||||
cogl_texture_get_height (*texture) == height &&
|
cogl_multi_plane_texture_get_height (*texture) == height &&
|
||||||
cogl_texture_get_components (*texture) == components &&
|
/*XXX cogl_texture_get_components (*texture) == components && */
|
||||||
_cogl_texture_get_format (*texture) == format)
|
cogl_multi_plane_texture_get_format (*texture) == format)
|
||||||
{
|
{
|
||||||
buffer->is_y_inverted = TRUE;
|
buffer->is_y_inverted = TRUE;
|
||||||
*changed_texture = FALSE;
|
*changed_texture = FALSE;
|
||||||
@ -230,56 +271,57 @@ shm_buffer_attach (MetaWaylandBuffer *buffer,
|
|||||||
|
|
||||||
cogl_clear_object (texture);
|
cogl_clear_object (texture);
|
||||||
|
|
||||||
|
/* Safely access the data inside the buffer */
|
||||||
wl_shm_buffer_begin_access (shm_buffer);
|
wl_shm_buffer_begin_access (shm_buffer);
|
||||||
|
data = wl_shm_buffer_get_data (shm_buffer);
|
||||||
|
|
||||||
bitmap = cogl_bitmap_new_for_data (cogl_context,
|
bitmaps = g_ptr_array_new_full (n_planes, cogl_object_unref);
|
||||||
width, height,
|
for (i = 0; i < n_planes; i++)
|
||||||
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);
|
|
||||||
|
|
||||||
if (!cogl_texture_allocate (new_texture, error))
|
|
||||||
{
|
{
|
||||||
g_clear_pointer (&new_texture, cogl_object_unref);
|
CoglBitmap *bitmap;
|
||||||
if (g_error_matches (*error, COGL_TEXTURE_ERROR, COGL_TEXTURE_ERROR_SIZE))
|
|
||||||
{
|
|
||||||
CoglTexture2DSliced *texture_sliced;
|
|
||||||
|
|
||||||
g_clear_error (error);
|
/* Internally, the texture's planes are laid out in memory as one
|
||||||
|
* contiguous block, so we have to consider any subsampling (based on the
|
||||||
|
* pixel format). */
|
||||||
|
if (i == 0)
|
||||||
|
offset = 0;
|
||||||
|
else
|
||||||
|
offset += (stride / h_factors[i-1]) * (height / v_factors[i-1]);
|
||||||
|
|
||||||
texture_sliced =
|
g_warning ("Creating plane %d, h_factor = %d, v_factor = %d, offset = %lu",
|
||||||
cogl_texture_2d_sliced_new_from_bitmap (bitmap,
|
i, h_factors[i], v_factors[i], offset);
|
||||||
COGL_TEXTURE_MAX_WASTE);
|
|
||||||
new_texture = COGL_TEXTURE (texture_sliced);
|
|
||||||
cogl_texture_set_components (new_texture, components);
|
|
||||||
|
|
||||||
if (!cogl_texture_allocate (new_texture, error))
|
bitmap = cogl_bitmap_new_for_data (cogl_context,
|
||||||
g_clear_pointer (&new_texture, cogl_object_unref);
|
width / h_factors[i],
|
||||||
}
|
height / v_factors[i],
|
||||||
|
format, /* XXX this we have to change later */
|
||||||
|
stride, /* XXX Do we need to change this too?*/
|
||||||
|
data + offset);
|
||||||
|
g_assert (bitmap);
|
||||||
|
|
||||||
|
g_ptr_array_add (bitmaps, bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
cogl_object_unref (bitmap);
|
*texture = cogl_multi_plane_texture_new_from_bitmaps (format,
|
||||||
|
(CoglBitmap **) g_ptr_array_free (bitmaps, FALSE),
|
||||||
|
n_planes, error);
|
||||||
|
|
||||||
wl_shm_buffer_end_access (shm_buffer);
|
wl_shm_buffer_end_access (shm_buffer);
|
||||||
|
|
||||||
if (!new_texture)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
*texture = new_texture;
|
|
||||||
*changed_texture = TRUE;
|
*changed_texture = TRUE;
|
||||||
buffer->is_y_inverted = TRUE;
|
buffer->is_y_inverted = TRUE;
|
||||||
|
|
||||||
|
g_warning ("Got the following multiplane texture:\n%s", cogl_multi_plane_texture_to_string (*texture));
|
||||||
|
/* g_ptr_array_free (bitmaps, TRUE); */
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
egl_image_buffer_attach (MetaWaylandBuffer *buffer,
|
egl_image_buffer_attach (MetaWaylandBuffer *buffer,
|
||||||
CoglTexture **texture,
|
CoglMultiPlaneTexture **texture,
|
||||||
gboolean *changed_texture,
|
gboolean *changed_texture,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
MetaBackend *backend = meta_get_backend ();
|
MetaBackend *backend = meta_get_backend ();
|
||||||
MetaEgl *egl = meta_backend_get_egl (backend);
|
MetaEgl *egl = meta_backend_get_egl (backend);
|
||||||
@ -288,8 +330,8 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
|
|||||||
EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context);
|
EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context);
|
||||||
int format, width, height, y_inverted;
|
int format, width, height, y_inverted;
|
||||||
CoglPixelFormat cogl_format;
|
CoglPixelFormat cogl_format;
|
||||||
EGLImageKHR egl_image;
|
guint i, n_planes;
|
||||||
CoglTexture2D *texture_2d;
|
GPtrArray *planes;
|
||||||
|
|
||||||
if (buffer->egl_image.texture)
|
if (buffer->egl_image.texture)
|
||||||
{
|
{
|
||||||
@ -299,6 +341,7 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Query the necessary properties */
|
||||||
if (!meta_egl_query_wayland_buffer (egl, egl_display, buffer->resource,
|
if (!meta_egl_query_wayland_buffer (egl, egl_display, buffer->resource,
|
||||||
EGL_TEXTURE_FORMAT, &format,
|
EGL_TEXTURE_FORMAT, &format,
|
||||||
error))
|
error))
|
||||||
@ -319,6 +362,7 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
|
|||||||
NULL))
|
NULL))
|
||||||
y_inverted = EGL_TRUE;
|
y_inverted = EGL_TRUE;
|
||||||
|
|
||||||
|
/* Map the EGL texture format to CoglPixelFormat, if possible */
|
||||||
switch (format)
|
switch (format)
|
||||||
{
|
{
|
||||||
case EGL_TEXTURE_RGB:
|
case EGL_TEXTURE_RGB:
|
||||||
@ -327,6 +371,14 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
|
|||||||
case EGL_TEXTURE_RGBA:
|
case EGL_TEXTURE_RGBA:
|
||||||
cogl_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE;
|
cogl_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE;
|
||||||
break;
|
break;
|
||||||
|
case EGL_TEXTURE_Y_UV_WL:
|
||||||
|
g_warning ("Got a NV12 color format texture!!");
|
||||||
|
cogl_format = COGL_PIXEL_FORMAT_NV12;
|
||||||
|
break;
|
||||||
|
case EGL_TEXTURE_Y_U_V_WL:
|
||||||
|
g_warning ("Got a YUV 4:4:4 color format texture!!");
|
||||||
|
cogl_format = COGL_PIXEL_FORMAT_YUV444;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
g_set_error (error, G_IO_ERROR,
|
g_set_error (error, G_IO_ERROR,
|
||||||
G_IO_ERROR_FAILED,
|
G_IO_ERROR_FAILED,
|
||||||
@ -334,27 +386,49 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The WL_bind_wayland_display spec states that EGL_NO_CONTEXT is to be used
|
n_planes = cogl_pixel_format_get_n_planes (cogl_format);
|
||||||
* in conjunction with the EGL_WAYLAND_BUFFER_WL target. */
|
planes = g_ptr_array_new_full (n_planes, cogl_object_unref);
|
||||||
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;
|
|
||||||
|
|
||||||
texture_2d = cogl_egl_texture_2d_new_from_image (cogl_context,
|
/* Each EGLImage is a plane in the final texture */
|
||||||
width, height,
|
for (i = 0; i < n_planes; i++)
|
||||||
cogl_format,
|
{
|
||||||
egl_image,
|
EGLint egl_attribs[3];
|
||||||
error);
|
EGLImageKHR egl_img;
|
||||||
|
CoglTexture2D *texture_2d;
|
||||||
|
|
||||||
meta_egl_destroy_image (egl, egl_display, egl_image, NULL);
|
/* Specify that we want the i'th plane */
|
||||||
|
egl_attribs[0] = EGL_WAYLAND_PLANE_WL;
|
||||||
|
egl_attribs[1] = i;
|
||||||
|
egl_attribs[2] = EGL_NONE;
|
||||||
|
|
||||||
if (!texture_2d)
|
/* The WL_bind_wayland_display spec states that EGL_NO_CONTEXT is to be
|
||||||
return FALSE;
|
* 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);
|
||||||
|
|
||||||
buffer->egl_image.texture = COGL_TEXTURE (texture_2d);
|
if (G_UNLIKELY (egl_img == EGL_NO_IMAGE_KHR))
|
||||||
|
goto on_error;
|
||||||
|
|
||||||
|
texture_2d = cogl_egl_texture_2d_new_from_image (cogl_context,
|
||||||
|
width, height,
|
||||||
|
cogl_format,
|
||||||
|
egl_img,
|
||||||
|
error);
|
||||||
|
|
||||||
|
meta_egl_destroy_image (egl, egl_display, egl_img, NULL);
|
||||||
|
|
||||||
|
if (G_UNLIKELY (!texture_2d))
|
||||||
|
goto on_error;
|
||||||
|
|
||||||
|
g_ptr_array_add (planes, texture_2d);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
buffer->egl_image.texture = cogl_multi_plane_texture_new (cogl_format,
|
||||||
|
(CoglTexture **) g_ptr_array_free (planes, FALSE),
|
||||||
|
n_planes);
|
||||||
buffer->is_y_inverted = !!y_inverted;
|
buffer->is_y_inverted = !!y_inverted;
|
||||||
|
|
||||||
cogl_clear_object (texture);
|
cogl_clear_object (texture);
|
||||||
@ -362,14 +436,19 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
|
|||||||
*changed_texture = TRUE;
|
*changed_texture = TRUE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
on_error:
|
||||||
|
g_ptr_array_free (planes, TRUE);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_WAYLAND_EGLSTREAM
|
#ifdef HAVE_WAYLAND_EGLSTREAM
|
||||||
static gboolean
|
static gboolean
|
||||||
egl_stream_buffer_attach (MetaWaylandBuffer *buffer,
|
egl_stream_buffer_attach (MetaWaylandBuffer *buffer,
|
||||||
CoglTexture **texture,
|
CoglMultiPlaneTexture **texture,
|
||||||
gboolean *changed_texture,
|
gboolean *changed_texture,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
MetaWaylandEglStream *stream = buffer->egl_stream.stream;
|
MetaWaylandEglStream *stream = buffer->egl_stream.stream;
|
||||||
|
|
||||||
@ -406,10 +485,10 @@ egl_stream_buffer_attach (MetaWaylandBuffer *buffer,
|
|||||||
* meta_wayland_buffer_attach(), which also might free it, as described above.
|
* meta_wayland_buffer_attach(), which also might free it, as described above.
|
||||||
*/
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
meta_wayland_buffer_attach (MetaWaylandBuffer *buffer,
|
meta_wayland_buffer_attach (MetaWaylandBuffer *buffer,
|
||||||
CoglTexture **texture,
|
CoglMultiPlaneTexture **texture,
|
||||||
gboolean *changed_texture,
|
gboolean *changed_texture,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (buffer->resource, FALSE);
|
g_return_val_if_fail (buffer->resource, FALSE);
|
||||||
|
|
||||||
@ -425,14 +504,18 @@ meta_wayland_buffer_attach (MetaWaylandBuffer *buffer,
|
|||||||
switch (buffer->type)
|
switch (buffer->type)
|
||||||
{
|
{
|
||||||
case META_WAYLAND_BUFFER_TYPE_SHM:
|
case META_WAYLAND_BUFFER_TYPE_SHM:
|
||||||
|
g_warning ("GOT SHM BUFFER");
|
||||||
return shm_buffer_attach (buffer, texture, changed_texture, error);
|
return shm_buffer_attach (buffer, texture, changed_texture, error);
|
||||||
case META_WAYLAND_BUFFER_TYPE_EGL_IMAGE:
|
case META_WAYLAND_BUFFER_TYPE_EGL_IMAGE:
|
||||||
|
g_warning ("GOT EGL IMAGE BUFFER");
|
||||||
return egl_image_buffer_attach (buffer, texture, changed_texture, error);
|
return egl_image_buffer_attach (buffer, texture, changed_texture, error);
|
||||||
#ifdef HAVE_WAYLAND_EGLSTREAM
|
#ifdef HAVE_WAYLAND_EGLSTREAM
|
||||||
case META_WAYLAND_BUFFER_TYPE_EGL_STREAM:
|
case META_WAYLAND_BUFFER_TYPE_EGL_STREAM:
|
||||||
|
g_warning ("GOT EGL STREAM BUFFER");
|
||||||
return egl_stream_buffer_attach (buffer, texture, changed_texture, error);
|
return egl_stream_buffer_attach (buffer, texture, changed_texture, error);
|
||||||
#endif
|
#endif
|
||||||
case META_WAYLAND_BUFFER_TYPE_DMA_BUF:
|
case META_WAYLAND_BUFFER_TYPE_DMA_BUF:
|
||||||
|
g_warning ("GOT DMA BUF BUFFER");
|
||||||
return meta_wayland_dma_buf_buffer_attach (buffer,
|
return meta_wayland_dma_buf_buffer_attach (buffer,
|
||||||
texture,
|
texture,
|
||||||
changed_texture,
|
changed_texture,
|
||||||
@ -466,55 +549,84 @@ meta_wayland_buffer_is_y_inverted (MetaWaylandBuffer *buffer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
process_shm_buffer_damage (MetaWaylandBuffer *buffer,
|
process_shm_buffer_damage (MetaWaylandBuffer *buffer,
|
||||||
CoglTexture *texture,
|
CoglMultiPlaneTexture *texture,
|
||||||
cairo_region_t *region,
|
cairo_region_t *region,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
struct wl_shm_buffer *shm_buffer;
|
struct wl_shm_buffer *shm_buffer;
|
||||||
int i, n_rectangles;
|
gint j, n_rectangles;
|
||||||
gboolean set_texture_failed = FALSE;
|
gboolean set_texture_failed = FALSE;
|
||||||
|
CoglPixelFormat format;
|
||||||
|
CoglTextureComponents components[3];
|
||||||
|
guint h_factors[3], v_factors[3], bpp[3];
|
||||||
|
guint offset = 0;
|
||||||
|
const uint8_t *data;
|
||||||
|
int32_t stride;
|
||||||
|
guint i, n_planes = cogl_multi_plane_texture_get_n_planes (texture);
|
||||||
|
|
||||||
n_rectangles = cairo_region_num_rectangles (region);
|
n_rectangles = cairo_region_num_rectangles (region);
|
||||||
|
|
||||||
shm_buffer = wl_shm_buffer_get (buffer->resource);
|
shm_buffer = wl_shm_buffer_get (buffer->resource);
|
||||||
|
|
||||||
|
/* Get the data */
|
||||||
wl_shm_buffer_begin_access (shm_buffer);
|
wl_shm_buffer_begin_access (shm_buffer);
|
||||||
|
data = wl_shm_buffer_get_data (shm_buffer);
|
||||||
|
|
||||||
for (i = 0; i < n_rectangles; i++)
|
/* Query the necessary properties */
|
||||||
|
stride = wl_shm_buffer_get_stride (shm_buffer);
|
||||||
|
shm_buffer_get_cogl_pixel_format (shm_buffer, &format, components);
|
||||||
|
cogl_pixel_format_get_subsampling_factors (format, h_factors, v_factors);
|
||||||
|
cogl_pixel_format_get_bits_per_pixel (format, bpp);
|
||||||
|
|
||||||
|
for (i = 0; i < n_planes; i++)
|
||||||
{
|
{
|
||||||
const uint8_t *data = wl_shm_buffer_get_data (shm_buffer);
|
CoglTexture *plane;
|
||||||
int32_t stride = wl_shm_buffer_get_stride (shm_buffer);
|
|
||||||
CoglPixelFormat format;
|
|
||||||
int bpp;
|
|
||||||
cairo_rectangle_int_t rect;
|
|
||||||
|
|
||||||
shm_buffer_get_cogl_pixel_format (shm_buffer, &format, NULL);
|
plane = cogl_multi_plane_texture_get_plane (texture, i);
|
||||||
bpp = _cogl_pixel_format_get_bytes_per_pixel (format);
|
|
||||||
cairo_region_get_rectangle (region, i, &rect);
|
|
||||||
|
|
||||||
if (!_cogl_texture_set_region (texture,
|
for (j = 0; j < n_rectangles; j++)
|
||||||
rect.width, rect.height,
|
|
||||||
format,
|
|
||||||
stride,
|
|
||||||
data + rect.x * bpp + rect.y * stride,
|
|
||||||
rect.x, rect.y,
|
|
||||||
0,
|
|
||||||
error))
|
|
||||||
{
|
{
|
||||||
set_texture_failed = TRUE;
|
cairo_rectangle_int_t rect;
|
||||||
break;
|
|
||||||
|
cairo_region_get_rectangle (region, i, &rect);
|
||||||
|
|
||||||
|
/* It's possible we get a faulty rectangle of size zero: ignore */
|
||||||
|
if (rect.height == 0 || rect.width == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Calculate the offset in the buffer */
|
||||||
|
if (i > 0)
|
||||||
|
offset += (stride / h_factors[i-1]) * (rect.height / v_factors[i-1]);
|
||||||
|
|
||||||
|
/* XXX don't we need the bpp here? */
|
||||||
|
if (!_cogl_texture_set_region (plane,
|
||||||
|
rect.width / h_factors[i],
|
||||||
|
rect.height / v_factors[i],
|
||||||
|
_cogl_texture_get_format (plane),
|
||||||
|
stride,
|
||||||
|
/* data + offset + rect.x * bpp + rect.y * stride, */
|
||||||
|
data + offset,
|
||||||
|
rect.x, rect.y,
|
||||||
|
0,
|
||||||
|
error))
|
||||||
|
{
|
||||||
|
set_texture_failed = TRUE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
wl_shm_buffer_end_access (shm_buffer);
|
wl_shm_buffer_end_access (shm_buffer);
|
||||||
|
|
||||||
return !set_texture_failed;
|
return !set_texture_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer,
|
meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer,
|
||||||
CoglTexture *texture,
|
CoglMultiPlaneTexture *texture,
|
||||||
cairo_region_t *region)
|
cairo_region_t *region)
|
||||||
{
|
{
|
||||||
gboolean res = FALSE;
|
gboolean res = FALSE;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
@ -56,19 +56,19 @@ struct _MetaWaylandBuffer
|
|||||||
MetaWaylandBufferType type;
|
MetaWaylandBufferType type;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
CoglTexture *texture;
|
CoglMultiPlaneTexture *texture;
|
||||||
} egl_image;
|
} egl_image;
|
||||||
|
|
||||||
#ifdef HAVE_WAYLAND_EGLSTREAM
|
#ifdef HAVE_WAYLAND_EGLSTREAM
|
||||||
struct {
|
struct {
|
||||||
MetaWaylandEglStream *stream;
|
MetaWaylandEglStream *stream;
|
||||||
CoglTexture *texture;
|
CoglMultiPlaneTexture *texture;
|
||||||
} egl_stream;
|
} egl_stream;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
MetaWaylandDmaBufBuffer *dma_buf;
|
MetaWaylandDmaBufBuffer *dma_buf;
|
||||||
CoglTexture *texture;
|
CoglMultiPlaneTexture *texture;
|
||||||
} dma_buf;
|
} dma_buf;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -80,14 +80,14 @@ MetaWaylandBuffer * meta_wayland_buffer_from_resource (struct wl_resou
|
|||||||
struct wl_resource * meta_wayland_buffer_get_resource (MetaWaylandBuffer *buffer);
|
struct wl_resource * meta_wayland_buffer_get_resource (MetaWaylandBuffer *buffer);
|
||||||
gboolean meta_wayland_buffer_is_realized (MetaWaylandBuffer *buffer);
|
gboolean meta_wayland_buffer_is_realized (MetaWaylandBuffer *buffer);
|
||||||
gboolean meta_wayland_buffer_realize (MetaWaylandBuffer *buffer);
|
gboolean meta_wayland_buffer_realize (MetaWaylandBuffer *buffer);
|
||||||
gboolean meta_wayland_buffer_attach (MetaWaylandBuffer *buffer,
|
gboolean meta_wayland_buffer_attach (MetaWaylandBuffer *buffer,
|
||||||
CoglTexture **texture,
|
CoglMultiPlaneTexture **texture,
|
||||||
gboolean *changed_texture,
|
gboolean *changed_texture,
|
||||||
GError **error);
|
GError **error);
|
||||||
CoglSnippet * meta_wayland_buffer_create_snippet (MetaWaylandBuffer *buffer);
|
CoglSnippet * meta_wayland_buffer_create_snippet (MetaWaylandBuffer *buffer);
|
||||||
gboolean meta_wayland_buffer_is_y_inverted (MetaWaylandBuffer *buffer);
|
gboolean meta_wayland_buffer_is_y_inverted (MetaWaylandBuffer *buffer);
|
||||||
void meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer,
|
void meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer,
|
||||||
CoglTexture *texture,
|
CoglMultiPlaneTexture *texture,
|
||||||
cairo_region_t *region);
|
cairo_region_t *region);
|
||||||
|
|
||||||
#endif /* META_WAYLAND_BUFFER_H */
|
#endif /* META_WAYLAND_BUFFER_H */
|
||||||
|
@ -58,7 +58,7 @@ update_cursor_sprite_texture (MetaWaylandCursorSurface *cursor_surface)
|
|||||||
MetaWaylandSurface *surface =
|
MetaWaylandSurface *surface =
|
||||||
meta_wayland_surface_role_get_surface (META_WAYLAND_SURFACE_ROLE (cursor_surface));
|
meta_wayland_surface_role_get_surface (META_WAYLAND_SURFACE_ROLE (cursor_surface));
|
||||||
MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (priv->cursor_sprite);
|
MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (priv->cursor_sprite);
|
||||||
CoglTexture *texture;
|
CoglMultiPlaneTexture *texture;
|
||||||
|
|
||||||
if (!priv->cursor_renderer)
|
if (!priv->cursor_renderer)
|
||||||
return;
|
return;
|
||||||
@ -66,8 +66,13 @@ update_cursor_sprite_texture (MetaWaylandCursorSurface *cursor_surface)
|
|||||||
texture = meta_wayland_surface_get_texture (surface);
|
texture = meta_wayland_surface_get_texture (surface);
|
||||||
if (texture)
|
if (texture)
|
||||||
{
|
{
|
||||||
|
CoglTexture *plane;
|
||||||
|
|
||||||
|
/* XXX We assume that we get a simple (single-plane) texture here */
|
||||||
|
plane = cogl_multi_plane_texture_get_plane (texture, 0);
|
||||||
|
|
||||||
meta_cursor_sprite_set_texture (cursor_sprite,
|
meta_cursor_sprite_set_texture (cursor_sprite,
|
||||||
texture,
|
plane,
|
||||||
priv->hot_x * surface->scale,
|
priv->hot_x * surface->scale,
|
||||||
priv->hot_y * surface->scale);
|
priv->hot_y * surface->scale);
|
||||||
}
|
}
|
||||||
|
@ -56,8 +56,9 @@ struct _MetaWaylandDmaBufBuffer
|
|||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
uint32_t drm_format;
|
uint32_t drm_format;
|
||||||
uint64_t drm_modifier;
|
|
||||||
bool is_y_inverted;
|
bool is_y_inverted;
|
||||||
|
|
||||||
|
uint64_t drm_modifier[META_WAYLAND_DMA_BUF_MAX_FDS];
|
||||||
int fds[META_WAYLAND_DMA_BUF_MAX_FDS];
|
int fds[META_WAYLAND_DMA_BUF_MAX_FDS];
|
||||||
int offsets[META_WAYLAND_DMA_BUF_MAX_FDS];
|
int offsets[META_WAYLAND_DMA_BUF_MAX_FDS];
|
||||||
unsigned int strides[META_WAYLAND_DMA_BUF_MAX_FDS];
|
unsigned int strides[META_WAYLAND_DMA_BUF_MAX_FDS];
|
||||||
@ -65,6 +66,140 @@ struct _MetaWaylandDmaBufBuffer
|
|||||||
|
|
||||||
G_DEFINE_TYPE (MetaWaylandDmaBufBuffer, meta_wayland_dma_buf_buffer, G_TYPE_OBJECT);
|
G_DEFINE_TYPE (MetaWaylandDmaBufBuffer, meta_wayland_dma_buf_buffer, G_TYPE_OBJECT);
|
||||||
|
|
||||||
|
static CoglPixelFormat
|
||||||
|
drm_buffer_get_cogl_pixel_format (MetaWaylandDmaBufBuffer *dma_buf)
|
||||||
|
{
|
||||||
|
g_warning ("Got dma format %d", dma_buf->drm_format);
|
||||||
|
switch (dma_buf->drm_format)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* NOTE: The cogl_format here is only used for texture color channel
|
||||||
|
* swizzling as compared to COGL_PIXEL_FORMAT_ARGB. It is *not* used
|
||||||
|
* for accessing the buffer memory. EGL will access the buffer
|
||||||
|
* memory according to the DRM fourcc code. Cogl will not mmap
|
||||||
|
* and access the buffer memory at all.
|
||||||
|
*/
|
||||||
|
case DRM_FORMAT_XRGB8888:
|
||||||
|
return COGL_PIXEL_FORMAT_RGB_888;
|
||||||
|
case DRM_FORMAT_ARGB8888:
|
||||||
|
return COGL_PIXEL_FORMAT_ARGB_8888_PRE;
|
||||||
|
case DRM_FORMAT_ARGB2101010:
|
||||||
|
return COGL_PIXEL_FORMAT_ARGB_2101010_PRE;
|
||||||
|
case DRM_FORMAT_RGB565:
|
||||||
|
return COGL_PIXEL_FORMAT_RGB_565;
|
||||||
|
case DRM_FORMAT_YUYV:
|
||||||
|
return COGL_PIXEL_FORMAT_YUYV;
|
||||||
|
case DRM_FORMAT_NV12:
|
||||||
|
return COGL_PIXEL_FORMAT_NV12;
|
||||||
|
case DRM_FORMAT_NV21:
|
||||||
|
return COGL_PIXEL_FORMAT_NV21;
|
||||||
|
case DRM_FORMAT_YUV410:
|
||||||
|
return COGL_PIXEL_FORMAT_YUV410;
|
||||||
|
case DRM_FORMAT_YVU410:
|
||||||
|
return COGL_PIXEL_FORMAT_YVU410;
|
||||||
|
case DRM_FORMAT_YUV411:
|
||||||
|
return COGL_PIXEL_FORMAT_YUV411;
|
||||||
|
case DRM_FORMAT_YVU411:
|
||||||
|
return COGL_PIXEL_FORMAT_YVU411;
|
||||||
|
case DRM_FORMAT_YUV420:
|
||||||
|
return COGL_PIXEL_FORMAT_YUV420;
|
||||||
|
case DRM_FORMAT_YVU420:
|
||||||
|
return COGL_PIXEL_FORMAT_YVU420;
|
||||||
|
case DRM_FORMAT_YUV422:
|
||||||
|
return COGL_PIXEL_FORMAT_YUV422;
|
||||||
|
case DRM_FORMAT_YVU422:
|
||||||
|
return COGL_PIXEL_FORMAT_YVU422;
|
||||||
|
case DRM_FORMAT_YUV444:
|
||||||
|
return COGL_PIXEL_FORMAT_YUV444;
|
||||||
|
case DRM_FORMAT_YVU444:
|
||||||
|
return COGL_PIXEL_FORMAT_YVU444;
|
||||||
|
default:
|
||||||
|
return COGL_PIXEL_FORMAT_ANY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static EGLImageKHR
|
||||||
|
create_egl_image_from_dmabuf (MetaEgl *egl,
|
||||||
|
EGLDisplay egl_display,
|
||||||
|
MetaWaylandDmaBufBuffer *dma_buf,
|
||||||
|
int32_t width,
|
||||||
|
int32_t height,
|
||||||
|
uint32_t drm_format,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
EGLint attribs[64];
|
||||||
|
int attr_idx = 0;
|
||||||
|
|
||||||
|
attribs[attr_idx++] = EGL_WIDTH;
|
||||||
|
attribs[attr_idx++] = width;
|
||||||
|
attribs[attr_idx++] = EGL_HEIGHT;
|
||||||
|
attribs[attr_idx++] = height;
|
||||||
|
attribs[attr_idx++] = EGL_LINUX_DRM_FOURCC_EXT;
|
||||||
|
attribs[attr_idx++] = drm_format;
|
||||||
|
|
||||||
|
attribs[attr_idx++] = EGL_DMA_BUF_PLANE0_FD_EXT;
|
||||||
|
attribs[attr_idx++] = dma_buf->fds[0];
|
||||||
|
attribs[attr_idx++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
|
||||||
|
attribs[attr_idx++] = dma_buf->offsets[0];
|
||||||
|
attribs[attr_idx++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
|
||||||
|
attribs[attr_idx++] = dma_buf->strides[0];
|
||||||
|
attribs[attr_idx++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT;
|
||||||
|
attribs[attr_idx++] = dma_buf->drm_modifier[0] & 0xffffffff;
|
||||||
|
attribs[attr_idx++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT;
|
||||||
|
attribs[attr_idx++] = dma_buf->drm_modifier[0] >> 32;
|
||||||
|
|
||||||
|
if (dma_buf->fds[1] >= 0)
|
||||||
|
{
|
||||||
|
attribs[attr_idx++] = EGL_DMA_BUF_PLANE1_FD_EXT;
|
||||||
|
attribs[attr_idx++] = dma_buf->fds[1];
|
||||||
|
attribs[attr_idx++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT;
|
||||||
|
attribs[attr_idx++] = dma_buf->offsets[1];
|
||||||
|
attribs[attr_idx++] = EGL_DMA_BUF_PLANE1_PITCH_EXT;
|
||||||
|
attribs[attr_idx++] = dma_buf->strides[1];
|
||||||
|
attribs[attr_idx++] = EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT;
|
||||||
|
attribs[attr_idx++] = dma_buf->drm_modifier[1] & 0xffffffff;
|
||||||
|
attribs[attr_idx++] = EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT;
|
||||||
|
attribs[attr_idx++] = dma_buf->drm_modifier[1] >> 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dma_buf->fds[2] >= 0)
|
||||||
|
{
|
||||||
|
attribs[attr_idx++] = EGL_DMA_BUF_PLANE2_FD_EXT;
|
||||||
|
attribs[attr_idx++] = dma_buf->fds[2];
|
||||||
|
attribs[attr_idx++] = EGL_DMA_BUF_PLANE2_OFFSET_EXT;
|
||||||
|
attribs[attr_idx++] = dma_buf->offsets[2];
|
||||||
|
attribs[attr_idx++] = EGL_DMA_BUF_PLANE2_PITCH_EXT;
|
||||||
|
attribs[attr_idx++] = dma_buf->strides[2];
|
||||||
|
attribs[attr_idx++] = EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT;
|
||||||
|
attribs[attr_idx++] = dma_buf->drm_modifier[2] & 0xffffffff;
|
||||||
|
attribs[attr_idx++] = EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT;
|
||||||
|
attribs[attr_idx++] = dma_buf->drm_modifier[2] >> 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dma_buf->fds[3] >= 0)
|
||||||
|
{
|
||||||
|
attribs[attr_idx++] = EGL_DMA_BUF_PLANE3_FD_EXT;
|
||||||
|
attribs[attr_idx++] = dma_buf->fds[3];
|
||||||
|
attribs[attr_idx++] = EGL_DMA_BUF_PLANE3_OFFSET_EXT;
|
||||||
|
attribs[attr_idx++] = dma_buf->offsets[3];
|
||||||
|
attribs[attr_idx++] = EGL_DMA_BUF_PLANE3_PITCH_EXT;
|
||||||
|
attribs[attr_idx++] = dma_buf->strides[3];
|
||||||
|
attribs[attr_idx++] = EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT;
|
||||||
|
attribs[attr_idx++] = dma_buf->drm_modifier[3] & 0xffffffff;
|
||||||
|
attribs[attr_idx++] = EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT;
|
||||||
|
attribs[attr_idx++] = dma_buf->drm_modifier[3] >> 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
attribs[attr_idx++] = EGL_NONE;
|
||||||
|
|
||||||
|
/* The EXT_image_dma_buf_import spec states that EGL_NO_CONTEXT is to be
|
||||||
|
* used in conjunction with the EGL_LINUX_DMA_BUF_EXT target. Similarly,
|
||||||
|
* the native buffer is named in the attribs. */
|
||||||
|
return meta_egl_create_image (egl, egl_display, EGL_NO_CONTEXT,
|
||||||
|
EGL_LINUX_DMA_BUF_EXT, NULL, attribs,
|
||||||
|
error);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer *buffer,
|
meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer *buffer,
|
||||||
GError **error)
|
GError **error)
|
||||||
@ -76,137 +211,71 @@ meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer *buffer,
|
|||||||
EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context);
|
EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context);
|
||||||
MetaWaylandDmaBufBuffer *dma_buf = buffer->dma_buf.dma_buf;
|
MetaWaylandDmaBufBuffer *dma_buf = buffer->dma_buf.dma_buf;
|
||||||
CoglPixelFormat cogl_format;
|
CoglPixelFormat cogl_format;
|
||||||
EGLImageKHR egl_image;
|
GPtrArray *planes;
|
||||||
CoglTexture2D *texture;
|
guint i = 0, n_planes = 1;
|
||||||
EGLint attribs[64];
|
|
||||||
int attr_idx = 0;
|
|
||||||
|
|
||||||
if (buffer->dma_buf.texture)
|
if (buffer->dma_buf.texture)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
switch (dma_buf->drm_format)
|
cogl_format = drm_buffer_get_cogl_pixel_format (dma_buf);
|
||||||
|
g_warning ("Dmabuf: Got cogl format %s", cogl_pixel_format_to_string (cogl_format));
|
||||||
|
if (G_UNLIKELY (cogl_format == COGL_PIXEL_FORMAT_ANY))
|
||||||
{
|
{
|
||||||
/*
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
* NOTE: The cogl_format here is only used for texture color channel
|
|
||||||
* swizzling as compared to COGL_PIXEL_FORMAT_ARGB. It is *not* used
|
|
||||||
* for accessing the buffer memory. EGL will access the buffer
|
|
||||||
* memory according to the DRM fourcc code. Cogl will not mmap
|
|
||||||
* and access the buffer memory at all.
|
|
||||||
*/
|
|
||||||
case DRM_FORMAT_XRGB8888:
|
|
||||||
cogl_format = COGL_PIXEL_FORMAT_RGB_888;
|
|
||||||
break;
|
|
||||||
case DRM_FORMAT_ARGB8888:
|
|
||||||
cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE;
|
|
||||||
break;
|
|
||||||
case DRM_FORMAT_ARGB2101010:
|
|
||||||
cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010_PRE;
|
|
||||||
break;
|
|
||||||
case DRM_FORMAT_RGB565:
|
|
||||||
cogl_format = COGL_PIXEL_FORMAT_RGB_565;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
g_set_error (error, G_IO_ERROR,
|
|
||||||
G_IO_ERROR_FAILED,
|
|
||||||
"Unsupported buffer format %d", dma_buf->drm_format);
|
"Unsupported buffer format %d", dma_buf->drm_format);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
attribs[attr_idx++] = EGL_WIDTH;
|
n_planes = cogl_pixel_format_get_n_planes (cogl_format);
|
||||||
attribs[attr_idx++] = dma_buf->width;
|
planes = g_ptr_array_new_full (n_planes, cogl_object_unref);
|
||||||
attribs[attr_idx++] = EGL_HEIGHT;
|
|
||||||
attribs[attr_idx++] = dma_buf->height;
|
|
||||||
attribs[attr_idx++] = EGL_LINUX_DRM_FOURCC_EXT;
|
|
||||||
attribs[attr_idx++] = dma_buf->drm_format;
|
|
||||||
|
|
||||||
attribs[attr_idx++] = EGL_DMA_BUF_PLANE0_FD_EXT;
|
/* Each EGLImage is a plane in the final CoglMultiPlaneTexture */
|
||||||
attribs[attr_idx++] = dma_buf->fds[0];
|
for (i = 0; i < n_planes; i++)
|
||||||
attribs[attr_idx++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
|
|
||||||
attribs[attr_idx++] = dma_buf->offsets[0];
|
|
||||||
attribs[attr_idx++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
|
|
||||||
attribs[attr_idx++] = dma_buf->strides[0];
|
|
||||||
attribs[attr_idx++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT;
|
|
||||||
attribs[attr_idx++] = dma_buf->drm_modifier & 0xffffffff;
|
|
||||||
attribs[attr_idx++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT;
|
|
||||||
attribs[attr_idx++] = dma_buf->drm_modifier >> 32;
|
|
||||||
|
|
||||||
if (dma_buf->fds[1] >= 0)
|
|
||||||
{
|
{
|
||||||
attribs[attr_idx++] = EGL_DMA_BUF_PLANE1_FD_EXT;
|
EGLImageKHR egl_img;
|
||||||
attribs[attr_idx++] = dma_buf->fds[1];
|
CoglTexture2D *plane;
|
||||||
attribs[attr_idx++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT;
|
|
||||||
attribs[attr_idx++] = dma_buf->offsets[1];
|
egl_img = create_egl_image_from_dmabuf (egl,
|
||||||
attribs[attr_idx++] = EGL_DMA_BUF_PLANE1_PITCH_EXT;
|
egl_display,
|
||||||
attribs[attr_idx++] = dma_buf->strides[1];
|
dma_buf,
|
||||||
attribs[attr_idx++] = EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT;
|
dma_buf->width, dma_buf->height,
|
||||||
attribs[attr_idx++] = dma_buf->drm_modifier & 0xffffffff;
|
dma_buf->drm_format,
|
||||||
attribs[attr_idx++] = EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT;
|
error);
|
||||||
attribs[attr_idx++] = dma_buf->drm_modifier >> 32;
|
if (G_UNLIKELY (egl_img == EGL_NO_IMAGE_KHR))
|
||||||
|
goto on_error;
|
||||||
|
|
||||||
|
plane = cogl_egl_texture_2d_new_from_image (cogl_context,
|
||||||
|
dma_buf->width,
|
||||||
|
dma_buf->height,
|
||||||
|
cogl_format,
|
||||||
|
egl_img,
|
||||||
|
error);
|
||||||
|
|
||||||
|
meta_egl_destroy_image (egl, egl_display, egl_img, NULL);
|
||||||
|
|
||||||
|
if (G_UNLIKELY (!plane))
|
||||||
|
goto on_error;
|
||||||
|
|
||||||
|
g_ptr_array_add (planes, plane);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dma_buf->fds[2] >= 0)
|
buffer->dma_buf.texture = cogl_multi_plane_texture_new (cogl_format,
|
||||||
{
|
(CoglTexture **) g_ptr_array_free (planes, FALSE),
|
||||||
attribs[attr_idx++] = EGL_DMA_BUF_PLANE2_FD_EXT;
|
n_planes);
|
||||||
attribs[attr_idx++] = dma_buf->fds[2];
|
|
||||||
attribs[attr_idx++] = EGL_DMA_BUF_PLANE2_OFFSET_EXT;
|
|
||||||
attribs[attr_idx++] = dma_buf->offsets[2];
|
|
||||||
attribs[attr_idx++] = EGL_DMA_BUF_PLANE2_PITCH_EXT;
|
|
||||||
attribs[attr_idx++] = dma_buf->strides[2];
|
|
||||||
attribs[attr_idx++] = EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT;
|
|
||||||
attribs[attr_idx++] = dma_buf->drm_modifier & 0xffffffff;
|
|
||||||
attribs[attr_idx++] = EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT;
|
|
||||||
attribs[attr_idx++] = dma_buf->drm_modifier >> 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dma_buf->fds[3] >= 0)
|
|
||||||
{
|
|
||||||
attribs[attr_idx++] = EGL_DMA_BUF_PLANE3_FD_EXT;
|
|
||||||
attribs[attr_idx++] = dma_buf->fds[3];
|
|
||||||
attribs[attr_idx++] = EGL_DMA_BUF_PLANE3_OFFSET_EXT;
|
|
||||||
attribs[attr_idx++] = dma_buf->offsets[3];
|
|
||||||
attribs[attr_idx++] = EGL_DMA_BUF_PLANE3_PITCH_EXT;
|
|
||||||
attribs[attr_idx++] = dma_buf->strides[3];
|
|
||||||
attribs[attr_idx++] = EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT;
|
|
||||||
attribs[attr_idx++] = dma_buf->drm_modifier & 0xffffffff;
|
|
||||||
attribs[attr_idx++] = EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT;
|
|
||||||
attribs[attr_idx++] = dma_buf->drm_modifier >> 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
attribs[attr_idx++] = EGL_NONE;
|
|
||||||
attribs[attr_idx++] = EGL_NONE;
|
|
||||||
|
|
||||||
/* The EXT_image_dma_buf_import spec states that EGL_NO_CONTEXT is to be used
|
|
||||||
* in conjunction with the EGL_LINUX_DMA_BUF_EXT target. Similarly, the
|
|
||||||
* native buffer is named in the attribs. */
|
|
||||||
egl_image = meta_egl_create_image (egl, egl_display, EGL_NO_CONTEXT,
|
|
||||||
EGL_LINUX_DMA_BUF_EXT, NULL, attribs,
|
|
||||||
error);
|
|
||||||
if (egl_image == EGL_NO_IMAGE_KHR)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
texture = cogl_egl_texture_2d_new_from_image (cogl_context,
|
|
||||||
dma_buf->width,
|
|
||||||
dma_buf->height,
|
|
||||||
cogl_format,
|
|
||||||
egl_image,
|
|
||||||
error);
|
|
||||||
|
|
||||||
meta_egl_destroy_image (egl, egl_display, egl_image, NULL);
|
|
||||||
|
|
||||||
if (!texture)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
buffer->dma_buf.texture = COGL_TEXTURE (texture);
|
|
||||||
buffer->is_y_inverted = dma_buf->is_y_inverted;
|
buffer->is_y_inverted = dma_buf->is_y_inverted;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
on_error:
|
||||||
|
g_ptr_array_free (planes, TRUE);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
meta_wayland_dma_buf_buffer_attach (MetaWaylandBuffer *buffer,
|
meta_wayland_dma_buf_buffer_attach (MetaWaylandBuffer *buffer,
|
||||||
CoglTexture **texture,
|
CoglMultiPlaneTexture **texture,
|
||||||
gboolean *changed_texture,
|
gboolean *changed_texture,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
if (!meta_wayland_dma_buf_realize_texture (buffer, error))
|
if (!meta_wayland_dma_buf_realize_texture (buffer, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -234,7 +303,7 @@ buffer_params_add (struct wl_client *client,
|
|||||||
drm_modifier |= ((uint64_t) drm_modifier_lo) & 0xffffffff;
|
drm_modifier |= ((uint64_t) drm_modifier_lo) & 0xffffffff;
|
||||||
|
|
||||||
dma_buf = wl_resource_get_user_data (resource);
|
dma_buf = wl_resource_get_user_data (resource);
|
||||||
if (!dma_buf)
|
if (G_UNLIKELY (!dma_buf))
|
||||||
{
|
{
|
||||||
wl_resource_post_error (resource,
|
wl_resource_post_error (resource,
|
||||||
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_ALREADY_USED,
|
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_ALREADY_USED,
|
||||||
@ -242,7 +311,7 @@ buffer_params_add (struct wl_client *client,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (plane_idx >= META_WAYLAND_DMA_BUF_MAX_FDS)
|
if (G_UNLIKELY (plane_idx >= META_WAYLAND_DMA_BUF_MAX_FDS))
|
||||||
{
|
{
|
||||||
wl_resource_post_error (resource,
|
wl_resource_post_error (resource,
|
||||||
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_IDX,
|
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_IDX,
|
||||||
@ -251,7 +320,7 @@ buffer_params_add (struct wl_client *client,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dma_buf->fds[plane_idx] != -1)
|
if (G_UNLIKELY (dma_buf->fds[plane_idx] != -1))
|
||||||
{
|
{
|
||||||
wl_resource_post_error (resource,
|
wl_resource_post_error (resource,
|
||||||
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_SET,
|
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_SET,
|
||||||
@ -260,8 +329,8 @@ buffer_params_add (struct wl_client *client,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dma_buf->drm_modifier != DRM_FORMAT_MOD_INVALID &&
|
if (G_UNLIKELY (dma_buf->drm_modifier[plane_idx] != DRM_FORMAT_MOD_INVALID &&
|
||||||
dma_buf->drm_modifier != drm_modifier)
|
dma_buf->drm_modifier[plane_idx] != drm_modifier))
|
||||||
{
|
{
|
||||||
wl_resource_post_error (resource,
|
wl_resource_post_error (resource,
|
||||||
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_WL_BUFFER,
|
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_WL_BUFFER,
|
||||||
@ -269,8 +338,9 @@ buffer_params_add (struct wl_client *client,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dma_buf->drm_modifier = drm_modifier;
|
|
||||||
dma_buf->fds[plane_idx] = fd;
|
dma_buf->fds[plane_idx] = fd;
|
||||||
|
dma_buf->drm_modifier[plane_idx] = drm_modifier;
|
||||||
dma_buf->offsets[plane_idx] = offset;
|
dma_buf->offsets[plane_idx] = offset;
|
||||||
dma_buf->strides[plane_idx] = stride;
|
dma_buf->strides[plane_idx] = stride;
|
||||||
}
|
}
|
||||||
@ -550,6 +620,16 @@ dma_buf_bind (struct wl_client *client,
|
|||||||
send_modifiers (resource, DRM_FORMAT_XRGB8888);
|
send_modifiers (resource, DRM_FORMAT_XRGB8888);
|
||||||
send_modifiers (resource, DRM_FORMAT_ARGB2101010);
|
send_modifiers (resource, DRM_FORMAT_ARGB2101010);
|
||||||
send_modifiers (resource, DRM_FORMAT_RGB565);
|
send_modifiers (resource, DRM_FORMAT_RGB565);
|
||||||
|
send_modifiers (resource, DRM_FORMAT_NV12);
|
||||||
|
send_modifiers (resource, DRM_FORMAT_YUV410);
|
||||||
|
send_modifiers (resource, DRM_FORMAT_YVU410);
|
||||||
|
send_modifiers (resource, DRM_FORMAT_YUV411);
|
||||||
|
send_modifiers (resource, DRM_FORMAT_YVU420);
|
||||||
|
send_modifiers (resource, DRM_FORMAT_YVU420);
|
||||||
|
send_modifiers (resource, DRM_FORMAT_YUV422);
|
||||||
|
send_modifiers (resource, DRM_FORMAT_YVU422);
|
||||||
|
send_modifiers (resource, DRM_FORMAT_YUV444);
|
||||||
|
send_modifiers (resource, DRM_FORMAT_YVU444);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
@ -598,10 +678,12 @@ meta_wayland_dma_buf_buffer_init (MetaWaylandDmaBufBuffer *dma_buf)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
dma_buf->drm_modifier = DRM_FORMAT_MOD_INVALID;
|
|
||||||
|
|
||||||
for (i = 0; i < META_WAYLAND_DMA_BUF_MAX_FDS; i++)
|
for (i = 0; i < META_WAYLAND_DMA_BUF_MAX_FDS; i++)
|
||||||
dma_buf->fds[i] = -1;
|
{
|
||||||
|
dma_buf->drm_modifier[i] = DRM_FORMAT_MOD_INVALID;
|
||||||
|
dma_buf->fds[i] = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -42,10 +42,10 @@ typedef struct _MetaWaylandDmaBufBuffer MetaWaylandDmaBufBuffer;
|
|||||||
gboolean meta_wayland_dma_buf_init (MetaWaylandCompositor *compositor);
|
gboolean meta_wayland_dma_buf_init (MetaWaylandCompositor *compositor);
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
meta_wayland_dma_buf_buffer_attach (MetaWaylandBuffer *buffer,
|
meta_wayland_dma_buf_buffer_attach (MetaWaylandBuffer *buffer,
|
||||||
CoglTexture **texture,
|
CoglMultiPlaneTexture **texture,
|
||||||
gboolean *changed_texture,
|
gboolean *changed_texture,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
MetaWaylandDmaBufBuffer *
|
MetaWaylandDmaBufBuffer *
|
||||||
meta_wayland_dma_buf_from_buffer (MetaWaylandBuffer *buffer);
|
meta_wayland_dma_buf_from_buffer (MetaWaylandBuffer *buffer);
|
||||||
|
@ -132,7 +132,7 @@ struct _MetaWaylandEglStream
|
|||||||
|
|
||||||
EGLStreamKHR egl_stream;
|
EGLStreamKHR egl_stream;
|
||||||
MetaWaylandBuffer *buffer;
|
MetaWaylandBuffer *buffer;
|
||||||
CoglTexture2D *texture;
|
CoglMultiPlaneTexture *texture;
|
||||||
gboolean is_y_inverted;
|
gboolean is_y_inverted;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -183,7 +183,7 @@ stream_texture_destroyed (gpointer data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
alloc_egl_stream_texture (CoglTexture2D *texture,
|
alloc_egl_stream_texture (CoglTexture2D *texture_2d,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
@ -199,7 +199,7 @@ alloc_egl_stream_texture (CoglTexture2D *texture,
|
|||||||
error);
|
error);
|
||||||
}
|
}
|
||||||
|
|
||||||
CoglTexture2D *
|
CoglMultiPlaneTexture *
|
||||||
meta_wayland_egl_stream_create_texture (MetaWaylandEglStream *stream,
|
meta_wayland_egl_stream_create_texture (MetaWaylandEglStream *stream,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
@ -208,7 +208,7 @@ meta_wayland_egl_stream_create_texture (MetaWaylandEglStream *stream,
|
|||||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||||
CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
|
CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
|
||||||
EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context);
|
EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context);
|
||||||
CoglTexture2D *texture;
|
CoglTexture2D *texture_2d;
|
||||||
int width, height;
|
int width, height;
|
||||||
int y_inverted;
|
int y_inverted;
|
||||||
|
|
||||||
@ -230,29 +230,30 @@ meta_wayland_egl_stream_create_texture (MetaWaylandEglStream *stream,
|
|||||||
NULL))
|
NULL))
|
||||||
y_inverted = EGL_TRUE;
|
y_inverted = EGL_TRUE;
|
||||||
|
|
||||||
texture =
|
texture_2d =
|
||||||
cogl_texture_2d_new_from_egl_image_external (cogl_context,
|
cogl_texture_2d_new_from_egl_image_external (cogl_context,
|
||||||
width, height,
|
width, height,
|
||||||
alloc_egl_stream_texture,
|
alloc_egl_stream_texture,
|
||||||
g_object_ref (stream),
|
g_object_ref (stream),
|
||||||
stream_texture_destroyed,
|
stream_texture_destroyed,
|
||||||
error);
|
error);
|
||||||
if (!texture)
|
if (!texture_2d)
|
||||||
{
|
{
|
||||||
g_object_unref (stream);
|
g_object_unref (stream);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cogl_texture_allocate (COGL_TEXTURE (texture), error))
|
if (!cogl_texture_allocate (COGL_TEXTURE (texture_2d), error))
|
||||||
{
|
{
|
||||||
cogl_object_unref (texture);
|
cogl_object_unref (texture_2d);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream->texture = texture;
|
stream->texture = cogl_multi_plane_texture_new_single_plane (COGL_PIXEL_FORMAT_ANY,
|
||||||
|
COGL_TEXTURE (texture_2d));
|
||||||
stream->is_y_inverted = !!y_inverted;
|
stream->is_y_inverted = !!y_inverted;
|
||||||
|
|
||||||
return texture;
|
return stream->texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
@ -45,8 +45,8 @@ MetaWaylandEglStream * meta_wayland_egl_stream_new (MetaWaylandBuffer *buffer,
|
|||||||
gboolean meta_wayland_egl_stream_attach (MetaWaylandEglStream *stream,
|
gboolean meta_wayland_egl_stream_attach (MetaWaylandEglStream *stream,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
CoglTexture2D * meta_wayland_egl_stream_create_texture (MetaWaylandEglStream *stream,
|
CoglMultiPlaneTexture * meta_wayland_egl_stream_create_texture (MetaWaylandEglStream *stream,
|
||||||
GError **error);
|
GError **error);
|
||||||
CoglSnippet * meta_wayland_egl_stream_create_snippet (void);
|
CoglSnippet * meta_wayland_egl_stream_create_snippet (void);
|
||||||
|
|
||||||
gboolean meta_wayland_egl_stream_is_y_inverted (MetaWaylandEglStream *stream);
|
gboolean meta_wayland_egl_stream_is_y_inverted (MetaWaylandEglStream *stream);
|
||||||
|
@ -153,7 +153,7 @@ meta_wayland_shell_surface_surface_commit (MetaWaylandSurfaceRole *surface_role
|
|||||||
MetaWaylandSurfaceRoleClass *surface_role_class;
|
MetaWaylandSurfaceRoleClass *surface_role_class;
|
||||||
MetaWindow *window;
|
MetaWindow *window;
|
||||||
MetaWaylandBuffer *buffer;
|
MetaWaylandBuffer *buffer;
|
||||||
CoglTexture *texture;
|
CoglMultiPlaneTexture *texture;
|
||||||
double scale;
|
double scale;
|
||||||
|
|
||||||
surface_role_class =
|
surface_role_class =
|
||||||
@ -171,8 +171,8 @@ meta_wayland_shell_surface_surface_commit (MetaWaylandSurfaceRole *surface_role
|
|||||||
scale = meta_wayland_actor_surface_calculate_scale (actor_surface);
|
scale = meta_wayland_actor_surface_calculate_scale (actor_surface);
|
||||||
texture = meta_wayland_surface_get_texture (surface);
|
texture = meta_wayland_surface_get_texture (surface);
|
||||||
|
|
||||||
window->buffer_rect.width = cogl_texture_get_width (texture) * scale;
|
window->buffer_rect.width = cogl_multi_plane_texture_get_width (texture) * scale;
|
||||||
window->buffer_rect.height = cogl_texture_get_height (texture) * scale;
|
window->buffer_rect.height = cogl_multi_plane_texture_get_height (texture) * scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -247,7 +247,7 @@ get_buffer_width (MetaWaylandSurface *surface)
|
|||||||
MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
|
MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
|
||||||
|
|
||||||
if (buffer)
|
if (buffer)
|
||||||
return cogl_texture_get_width (surface->texture);
|
return cogl_multi_plane_texture_get_width (surface->texture);
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -258,7 +258,7 @@ get_buffer_height (MetaWaylandSurface *surface)
|
|||||||
MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
|
MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
|
||||||
|
|
||||||
if (buffer)
|
if (buffer)
|
||||||
return cogl_texture_get_height (surface->texture);
|
return cogl_multi_plane_texture_get_height (surface->texture);
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -722,7 +722,7 @@ meta_wayland_surface_apply_pending_state (MetaWaylandSurface *surface,
|
|||||||
if (changed_texture && meta_wayland_surface_get_actor (surface))
|
if (changed_texture && meta_wayland_surface_get_actor (surface))
|
||||||
{
|
{
|
||||||
MetaShapedTexture *stex;
|
MetaShapedTexture *stex;
|
||||||
CoglTexture *texture;
|
CoglMultiPlaneTexture *texture;
|
||||||
CoglSnippet *snippet;
|
CoglSnippet *snippet;
|
||||||
gboolean is_y_inverted;
|
gboolean is_y_inverted;
|
||||||
|
|
||||||
@ -1843,7 +1843,7 @@ meta_wayland_surface_is_shortcuts_inhibited (MetaWaylandSurface *surface,
|
|||||||
return g_hash_table_contains (surface->shortcut_inhibited_seats, seat);
|
return g_hash_table_contains (surface->shortcut_inhibited_seats, seat);
|
||||||
}
|
}
|
||||||
|
|
||||||
CoglTexture *
|
CoglMultiPlaneTexture *
|
||||||
meta_wayland_surface_get_texture (MetaWaylandSurface *surface)
|
meta_wayland_surface_get_texture (MetaWaylandSurface *surface)
|
||||||
{
|
{
|
||||||
return surface->texture;
|
return surface->texture;
|
||||||
|
@ -149,7 +149,7 @@ struct _MetaWaylandSurface
|
|||||||
GHashTable *outputs_to_destroy_notify_id;
|
GHashTable *outputs_to_destroy_notify_id;
|
||||||
MetaMonitorTransform buffer_transform;
|
MetaMonitorTransform buffer_transform;
|
||||||
|
|
||||||
CoglTexture *texture;
|
CoglMultiPlaneTexture *texture;
|
||||||
|
|
||||||
/* Buffer reference state. */
|
/* Buffer reference state. */
|
||||||
struct {
|
struct {
|
||||||
@ -319,7 +319,7 @@ void meta_wayland_surface_restore_shortcuts (MetaWaylandSurface *
|
|||||||
gboolean meta_wayland_surface_is_shortcuts_inhibited (MetaWaylandSurface *surface,
|
gboolean meta_wayland_surface_is_shortcuts_inhibited (MetaWaylandSurface *surface,
|
||||||
MetaWaylandSeat *seat);
|
MetaWaylandSeat *seat);
|
||||||
|
|
||||||
CoglTexture * meta_wayland_surface_get_texture (MetaWaylandSurface *surface);
|
CoglMultiPlaneTexture * meta_wayland_surface_get_texture (MetaWaylandSurface *surface);
|
||||||
|
|
||||||
MetaSurfaceActor * meta_wayland_surface_get_actor (MetaWaylandSurface *surface);
|
MetaSurfaceActor * meta_wayland_surface_get_actor (MetaWaylandSurface *surface);
|
||||||
|
|
||||||
|
@ -306,6 +306,26 @@ meta_wayland_log_func (const char *fmt,
|
|||||||
g_free (str);
|
g_free (str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_supported_shm_formats (struct wl_display *display)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
/* Note that a Wayland compositor should support WL_SHM_FORMAT_ARGB8888 and
|
||||||
|
* WL_SHM_FORMAT_XRGB8888 by default, so no need to add it here. */
|
||||||
|
static const guint32 SUPPORTED_FORMATS[] = {
|
||||||
|
WL_SHM_FORMAT_NV12,
|
||||||
|
WL_SHM_FORMAT_NV21,
|
||||||
|
WL_SHM_FORMAT_YUV422,
|
||||||
|
WL_SHM_FORMAT_YUV444,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (SUPPORTED_FORMATS); i++)
|
||||||
|
{
|
||||||
|
wl_display_add_shm_format (display, SUPPORTED_FORMATS[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_wayland_compositor_init (MetaWaylandCompositor *compositor)
|
meta_wayland_compositor_init (MetaWaylandCompositor *compositor)
|
||||||
{
|
{
|
||||||
@ -318,6 +338,8 @@ meta_wayland_compositor_init (MetaWaylandCompositor *compositor)
|
|||||||
compositor->wayland_display = wl_display_create ();
|
compositor->wayland_display = wl_display_create ();
|
||||||
if (compositor->wayland_display == NULL)
|
if (compositor->wayland_display == NULL)
|
||||||
g_error ("Failed to create the global wl_display");
|
g_error ("Failed to create the global wl_display");
|
||||||
|
|
||||||
|
add_supported_shm_formats (compositor->wayland_display);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Loading…
Reference in New Issue
Block a user