Compare commits

...

18 Commits

Author SHA1 Message Date
Niels De Graef
a3fb239344 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
2019-06-03 16:06:23 +02:00
Niels De Graef
d3ed857ebc cogl: Map CoglPixelFormats to their specific properties
By providing an (internal) table to map `CoglPixelFormat`s to their
respective properties  we will be able to get rid of the unusual enum
values in the future. This is something we will need once we want to
have support for more pixel formats (such as YUV-based formats).

As an extra feature, we provide a `to_string()` method, which is quite
useful for debugging purposes (rather than deciphering enum values).

https://gitlab.gnome.org/GNOME/mutter/merge_requests/524
2019-06-03 15:09:58 +02:00
Niels De Graef
69cebc2a70 cogl: Put CoglPixelFormat code into its own file
We're going to add some features and extra code to CoglPixelFormat, so
it's much nicer to have it in once place. Notice also that it doesn't
make sense that e.g. `_cogl_pixel_format_get_bytes_per_pixel()` were in
a private header, since they were being exported anyway.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/524
2019-06-03 15:09:45 +02:00
Florian Müllner
13a1624c10 cogl-path: Undeprecate framebuffer functions
It looks like deprecating the functions with explicit framebuffer/pipeline
arguments made it to (cogl) master by mistake:

https://mail.gnome.org/archives/clutter-list/2016-April/msg00008.html

We now use one of them, so this is a good time to undeprecate the lot.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/597
2019-05-28 18:35:04 +02:00
Florian Müllner
30d6e3abe2 clutter-text: Fix selection color drawing
Commit cabcad185 removed the call to cogl_set_source_color4ub() before
cogl_fill_path(), so instead of the previously assigned selection color,
the background is drawn with the last set source.

In order to honour the newly added framebuffer parameter and still apply
the correct color, switch from cogl_fill_path() to the (deprecated!)
cogl_framebuffer_fill_path() method.

https://gitlab.gnome.org/GNOME/mutter/issues/494
2019-05-28 18:34:34 +02:00
Marco Trevisan (Treviño)
18e44bb64c cogl/pipeline: Don't try to access to free'd pointer data
When free'ing a pipeline we destroy the BigState first and then the fragment and
vertex snippets lists using the big state pointer which is now invalid.
This causes a crash  when G_SLICE=always-malloc is set and using MALLOC_CHECK_.

So, invert the operations by free'ing the snippet lists first, and the big state
afterwards.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/581


(cherry picked from commit 7e0d185120)
2019-05-27 22:39:51 +00:00
Marco Trevisan (Treviño)
15803b9558 wayland-seat: Use g_free to cleanup MetaWaylandSeat
MetaWaylandSeat is allocated using g_new0(), and thus we should use g_free() to
destroy it.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/581


(cherry picked from commit 0405786573)
2019-05-27 22:37:45 +00:00
Marco Trevisan (Treviño)
3fdc651179 cursor-renderer-native: Free MetaCursorNativePrivate struct
Fix a small leak in native renderer.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/581


(cherry picked from commit b016ff29f6)
2019-05-27 22:34:47 +00:00
Florian Müllner
189f71f5d1 Bump version to 3.32.2
Update NEWS.
2019-05-14 14:01:28 +00:00
Carlos Garnacho
0a3cddeecf core: Check environment variables before giving to GAppLaunchContext
Depending on the type of session, one or the other might be NULL, which
is not meant to be handled by these functions. Check for both DISPLAY
envvars before setting them on the GAppLaunchContext.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/586
2019-05-07 16:07:34 +02:00
Jonas Ådahl
ee92e4fe13 idle-monitor: Postpone dispatching of idle timeout if not ready
If we update the ready time while the source is already in the
to-dispatch list, changing the ready time doesn't have any effect, and
the source will still be dispatched. This could cause incorrect idle
watch firing causing the power management plugin in
gnome-settings-daemon to sometimes turn off monitors due to it believing
the user had been idle for some time, while in fact, they just logged
back in.

Fix this by not actually dispatching the idle timeout if the ready time
is in the future when actually dispatching.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/543
2019-05-07 16:01:58 +02:00
Jonas Ådahl
6933ce0976 idle-monitor: Use G_SOURCE_CONTINUE instead of TRUE
Returning TRUE is confusing, as it doesn't carry any relevant meaning.
Use G_SOURCE_CONTINUE to make it clearer that the source is here to
stay.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/543
2019-05-07 16:01:58 +02:00
Carlos Garnacho
f9d6627fe0 backends: Fallback to builtin panel for devices where all heuristics fail
This is 1) relatively likely as not all touchscreens are nice enough to
report a device size that will help us here and 2) Better than nothing if
everything fails anyway, as it will break on multi-monitor and non-default
monitor rotations.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/581
2019-05-03 23:48:29 +02:00
Marco Trevisan (Treviño)
668c44e66b compositor: Disconnect from stage signals on destruction
From this point there's not any need for the compositor to listen to signals
so we can disconnect from the stage ones we are connected to.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/556


(cherry picked from commit 3ba79961fe)
2019-05-01 05:11:17 +00:00
Marco Trevisan (Treviño)
3495a43810 compositor: Destroy window actors list on destruction
When the compositor is destroyed we should cleanup the list of window actors we
created and destroy them.
Since all the actors are added to the window_group or top_window_group we can
just destroy these containers (together with the feedback_group), and simply
free the windows list.

This is particularly needed under X11 because before we destroy the display, we
might do some cleanups as detaching the surface pixmaps and freeing the damages
and if this happens at later point (for example when triggered by garbage
collector in gnome-shell), we might crash because the x11 dpy reference is
already gone.

Destroying the window actors instead, ensures we avoid any further call to X11
related functions and that we release the actors XServer resources.

Fixes https://gitlab.gnome.org/GNOME/mutter/issues/576


(cherry picked from commit 7718e67f5c)
2019-05-01 05:10:51 +00:00
Olivier Fourdan
9a795d3d0f input-settings: Use 0 initialized struct for kbd a11y
Make sure our keyboard accessibility settings structure is all zero
initialized, to avoid potential padding issues on some platform when
comparing settings.

Reported by Daniel van Vugt on IRC.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/552


(cherry picked from commit eccf7b105c)
2019-04-30 10:57:45 +00:00
Olivier Fourdan
abc3fdcc65 clutter/x11: disable mousekeys with Numlock ON
GNOME documentation on accessibility features states that mousekeys
work only when NumLock is OFF:

  https://help.gnome.org/users/gnome-help/stable/mouse-mousekeys.html

Change the clutter/x11 implementation to match the documentation, i.e.
disable mousekeys when NumLock in ON so that switching NumLock ON
restores the numeric keypad behaviour.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/530
(cherry picked from commit 251fa024c4)
2019-04-19 16:18:18 +02:00
Olivier Fourdan
4705a31049 clutter/evdev: disable mousekeys with Numlock ON
The clutter/evdev implementation of mousekeys is designed after the
current implementation in X11, and works when the setting is enabled
regardless of the status of NumLock.

The GNOME documentation on accessibility features states however that
mousekeys work only when NumLock is OFF:

  https://help.gnome.org/users/gnome-help/stable/mouse-mousekeys.html

Change the clutter/evdev implementation to match the documentation, i.e.
disable mousekeys when NumLock in ON so that switching NumLock ON
restores the numeric keypad behaviour.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/530
(cherry picked from commit 471b61bd14)
2019-04-19 16:18:12 +02:00
56 changed files with 2842 additions and 734 deletions

11
NEWS
View File

@@ -1,3 +1,14 @@
3.32.2
======
* Disable mouse keys with Numlock on [Olivier; #530]
* Fix crash when restarting on X11 [Marco; #576]
* Fix mapping of touchscreens that don't report dimensions [Carlos; #581]
* Fix spurious idle signals that prevent session unblank [Jonas; !543]
* Misc. bug fixes and cleanups [Olivier, Marco, Carlos; !552, !557, #586]
Contributors:
Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Marco Trevisan (Treviño)
3.32.1
======
* Fix fallback app menu on wayland [Florian; #493]

View File

@@ -1975,6 +1975,7 @@ selection_paint (ClutterText *self,
else
{
/* Paint selection background first */
CoglPipeline *color_pipeline = cogl_pipeline_copy (default_color_pipeline);
PangoLayout *layout = clutter_text_get_layout (self);
CoglPath *selection_path = cogl_path_new ();
CoglColor cogl_color = { 0, };
@@ -1987,11 +1988,19 @@ selection_paint (ClutterText *self,
else
color = &priv->text_color;
cogl_color_init_from_4ub (&cogl_color,
color->red,
color->green,
color->blue,
paint_opacity * color->alpha / 255);
cogl_color_premultiply (&cogl_color);
cogl_pipeline_set_color (color_pipeline, &cogl_color);
clutter_text_foreach_selection_rectangle_prescaled (self,
add_selection_rectangle_to_path,
selection_path);
cogl_path_fill (selection_path);
cogl_framebuffer_fill_path (fb, color_pipeline, selection_path);
/* Paint selected text */
cogl_framebuffer_push_path_clip (fb, selection_path);

View File

@@ -855,6 +855,14 @@ emulate_pointer_motion (ClutterInputDeviceEvdev *device,
clutter_virtual_input_device_notify_relative_motion (device->mousekeys_virtual_device,
time_us, dx_motion, dy_motion);
}
static gboolean
is_numlock_active (ClutterInputDeviceEvdev *device)
{
ClutterSeatEvdev *seat = device->seat;
return xkb_state_mod_name_is_active (seat->xkb,
"Mod2",
XKB_STATE_MODS_LOCKED);
}
static void
enable_mousekeys (ClutterInputDeviceEvdev *device)
@@ -1013,6 +1021,10 @@ handle_mousekeys_press (ClutterEvent *event,
if (!(event->key.flags & CLUTTER_EVENT_FLAG_SYNTHETIC))
stop_mousekeys_move (device);
/* Do not handle mousekeys if NumLock is ON */
if (is_numlock_active (device))
return FALSE;
/* Button selection */
switch (event->key.keyval)
{
@@ -1084,6 +1096,10 @@ static gboolean
handle_mousekeys_release (ClutterEvent *event,
ClutterInputDeviceEvdev *device)
{
/* Do not handle mousekeys if NumLock is ON */
if (is_numlock_active (device))
return FALSE;
switch (event->key.keyval)
{
case XKB_KEY_KP_0:

View File

@@ -54,6 +54,7 @@
#include "clutter-main.h"
#include "clutter-private.h"
#include "clutter-settings-private.h"
#include "clutter-xkb-a11y-x11.h"
G_DEFINE_TYPE (ClutterBackendX11, clutter_backend_x11, CLUTTER_TYPE_BACKEND)
@@ -276,6 +277,20 @@ clutter_backend_x11_create_device_manager (ClutterBackendX11 *backend_x11)
_clutter_backend_add_event_translator (backend, translator);
}
static void
on_keymap_state_change (ClutterKeymapX11 *keymap_x11,
gpointer data)
{
ClutterDeviceManager *device_manager = CLUTTER_DEVICE_MANAGER (data);
ClutterKbdA11ySettings kbd_a11y_settings;
/* On keymaps state change, just reapply the current settings, it'll
* take care of enabling/disabling mousekeys based on NumLock state.
*/
clutter_device_manager_get_kbd_a11y_settings (device_manager, &kbd_a11y_settings);
clutter_device_manager_x11_apply_kbd_a11y_settings (device_manager, &kbd_a11y_settings);
}
static void
clutter_backend_x11_create_keymap (ClutterBackendX11 *backend_x11)
{
@@ -292,6 +307,11 @@ clutter_backend_x11_create_keymap (ClutterBackendX11 *backend_x11)
backend = CLUTTER_BACKEND (backend_x11);
translator = CLUTTER_EVENT_TRANSLATOR (backend_x11->keymap);
_clutter_backend_add_event_translator (backend, translator);
g_signal_connect (backend_x11->keymap,
"state-changed",
G_CALLBACK (on_keymap_state_change),
backend->device_manager);
}
}

View File

@@ -241,8 +241,13 @@ clutter_device_manager_x11_apply_kbd_a11y_settings (ClutterDeviceManager *devi
}
/* mouse keys */
if (set_xkb_ctrl (desc, kbd_a11y_settings->controls,
CLUTTER_A11Y_MOUSE_KEYS_ENABLED, XkbMouseKeysMask | XkbMouseKeysAccelMask))
if (clutter_keymap_get_num_lock_state (CLUTTER_KEYMAP (backend_x11->keymap)))
{
/* Disable mousekeys when NumLock is ON */
desc->ctrls->enabled_ctrls &= ~(XkbMouseKeysMask | XkbMouseKeysAccelMask);
}
else if (set_xkb_ctrl (desc, kbd_a11y_settings->controls,
CLUTTER_A11Y_MOUSE_KEYS_ENABLED, XkbMouseKeysMask | XkbMouseKeysAccelMask))
{
gint mk_max_speed;
gint mk_accel_time;

View File

@@ -460,9 +460,7 @@ cogl_path_fill (CoglPath *path);
* use while filling a path.</note>
*
* Stability: unstable
* Deprecated: 1.16: Use cogl_path_fill() instead
*/
COGL_DEPRECATED_FOR (cogl_path_fill)
void
cogl_framebuffer_fill_path (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
@@ -492,9 +490,7 @@ cogl_path_stroke (CoglPath *path);
* regardless of the current transformation matrix.
*
* Stability: unstable
* Deprecated: 1.16: Use cogl_path_stroke() instead
*/
COGL_DEPRECATED_FOR (cogl_path_stroke)
void
cogl_framebuffer_stroke_path (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
@@ -529,9 +525,7 @@ cogl_framebuffer_push_path_clip (CoglFramebuffer *framebuffer,
*
* Since: 1.8
* Stability: Unstable
* Deprecated: 1.16: Use cogl_framebuffer_push_path_clip() instead
*/
COGL_DEPRECATED_FOR (cogl_framebuffer_push_path_clip)
void
cogl_clip_push_from_path (CoglPath *path);

View File

@@ -1504,7 +1504,6 @@ cogl_framebuffer_push_path_clip (CoglFramebuffer *framebuffer,
COGL_FRAMEBUFFER_STATE_CLIP;
}
/* XXX: deprecated */
void
cogl_clip_push_from_path (CoglPath *path)
{
@@ -1575,7 +1574,6 @@ _cogl_path_build_stroke_attribute_buffer (CoglPath *path)
data->stroke_n_attributes = n_attributes;
}
/* XXX: deprecated */
void
cogl_framebuffer_fill_path (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
@@ -1588,7 +1586,6 @@ cogl_framebuffer_fill_path (CoglFramebuffer *framebuffer,
_cogl_path_fill_nodes (path, framebuffer, pipeline, 0 /* flags */);
}
/* XXX: deprecated */
void
cogl_framebuffer_stroke_path (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,

View File

@@ -320,7 +320,37 @@ _cogl_bitmap_needs_short_temp_buffer (CoglPixelFormat format)
case COGL_PIXEL_FORMAT_DEPTH_32:
case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
case COGL_PIXEL_FORMAT_ANY:
/* No support for YUV or multi-plane formats */
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 ();
case COGL_PIXEL_FORMAT_A_8:

View File

@@ -400,7 +400,37 @@ G_PASTE (_cogl_unpack_, component_size) (CoglPixelFormat format,
case COGL_PIXEL_FORMAT_DEPTH_32:
case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
case COGL_PIXEL_FORMAT_ANY:
/* No support for YUV or multi-plane formats */
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 ();
}
}
@@ -761,7 +791,37 @@ G_PASTE (_cogl_pack_, component_size) (CoglPixelFormat format,
case COGL_PIXEL_FORMAT_DEPTH_32:
case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
case COGL_PIXEL_FORMAT_ANY:
/* No support for YUV or multi-plane formats */
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 ();
}
}

View File

@@ -43,6 +43,7 @@ typedef struct _CoglBitmap CoglBitmap;
#include <cogl/cogl-buffer.h>
#include <cogl/cogl-context.h>
#include <cogl/cogl-pixel-buffer.h>
#include <cogl/cogl-pixel-format.h>
#include <glib-object.h>

View 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);
}

View 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

View File

@@ -455,9 +455,6 @@ _cogl_pipeline_free (CoglPipeline *pipeline)
_cogl_bitmask_destroy (&uniforms_state->changed_mask);
}
if (pipeline->differences & COGL_PIPELINE_STATE_NEEDS_BIG_STATE)
g_slice_free (CoglPipelineBigState, pipeline->big_state);
if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS)
{
g_list_foreach (pipeline->layer_differences,
@@ -471,6 +468,9 @@ _cogl_pipeline_free (CoglPipeline *pipeline)
if (pipeline->differences & COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS)
_cogl_pipeline_snippet_list_free (&pipeline->big_state->fragment_snippets);
if (pipeline->differences & COGL_PIPELINE_STATE_NEEDS_BIG_STATE)
g_slice_free (CoglPipelineBigState, pipeline->big_state);
g_list_free (pipeline->deprecated_get_layers_list);
recursively_free_layer_caches (pipeline);

View 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;
}

View 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

View File

@@ -0,0 +1,687 @@
/*
* Cogl
*
* A Low Level GPU Graphics and Utilities API
*
* Copyright (C) 2007,2008,2009,2010 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*
*/
#include "cogl-config.h"
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include "cogl-pixel-format.h"
/* An entry to map CoglPixelFormats to their respective properties */
typedef struct _CoglPixelFormatInfo
{
CoglPixelFormat cogl_format;
const char *format_str;
int bpp; /* Bytes per pixel */
int aligned; /* Aligned components? (-1 if n/a) */
uint8_t n_planes;
} CoglPixelFormatInfo;
static const CoglPixelFormatInfo format_info_table[] = {
{
.cogl_format = COGL_PIXEL_FORMAT_ANY,
.format_str = "ANY",
.bpp = 0,
.aligned = -1,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_A_8,
.format_str = "A_8",
.bpp = 1,
.aligned = 1,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGB_565,
.format_str = "RGB_565",
.bpp = 2,
.aligned = 0,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_4444,
.format_str = "RGBA_4444",
.bpp = 2,
.aligned = 0,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_5551,
.format_str = "RGBA_5551",
.bpp = 2,
.aligned = 0,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_YUV,
.format_str = "YUV",
.bpp = 0,
.aligned = -1,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_G_8,
.format_str = "G_8",
.bpp = 1,
.aligned = 1,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RG_88,
.format_str = "RG_88",
.bpp = 2,
.aligned = 1,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGB_888,
.format_str = "RGB_888",
.bpp = 3,
.aligned = 1,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_BGR_888,
.format_str = "BGR_888",
.bpp = 3,
.aligned = 1,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_8888,
.format_str = "RGBA_8888",
.bpp = 4,
.aligned = 1,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_BGRA_8888,
.format_str = "BGRA_8888",
.bpp = 4,
.aligned = 1,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_ARGB_8888,
.format_str = "ARGB_8888",
.bpp = 4,
.aligned = 1,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_ABGR_8888,
.format_str = "ABGR_8888",
.bpp = 4,
.aligned = 1,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_1010102,
.format_str = "RGBA_1010102",
.bpp = 4,
.aligned = 0,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_BGRA_1010102,
.format_str = "BGRA_1010102",
.bpp = 4,
.aligned = 0,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010,
.format_str = "ARGB_2101010",
.bpp = 4,
.aligned = 0,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010,
.format_str = "ABGR_2101010",
.bpp = 4,
.aligned = 0,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE,
.format_str = "RGBA_8888_PRE",
.bpp = 4,
.aligned = 1,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_BGRA_8888_PRE,
.format_str = "BGRA_8888_PRE",
.bpp = 4,
.aligned = 1,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE,
.format_str = "ARGB_8888_PRE",
.bpp = 4,
.aligned = 1,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_ABGR_8888_PRE,
.format_str = "ABGR_8888_PRE",
.bpp = 4,
.aligned = 1,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_4444_PRE,
.format_str = "RGBA_4444_PRE",
.bpp = 2,
.aligned = 0,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_5551_PRE,
.format_str = "RGBA_5551_PRE",
.bpp = 2,
.aligned = 0,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_1010102_PRE,
.format_str = "RGBA_1010102_PRE",
.bpp = 4,
.aligned = 0,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_BGRA_1010102_PRE,
.format_str = "BGRA_1010102_PRE",
.bpp = 4,
.aligned = 0,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010_PRE,
.format_str = "ARGB_2101010_PRE",
.bpp = 4,
.aligned = 0,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010_PRE,
.format_str = "ABGR_2101010_PRE",
.bpp = 4,
.aligned = 0,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_DEPTH_16,
.format_str = "DEPTH_16",
.bpp = 2,
.aligned = 1,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_DEPTH_32,
.format_str = "DEPTH_32",
.bpp = 4,
.aligned = 1,
.n_planes = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8,
.format_str = "DEPTH_24_STENCIL_8",
.bpp = 4,
.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
},
};
/*
* Returns the number of bytes-per-pixel of a given format. The bpp
* can be extracted from the least significant nibble of the pixel
* format (see CoglPixelFormat).
*
* The mapping is the following (see discussion on bug #660188):
*
* 0 = undefined
* 1, 8 = 1 bpp (e.g. A_8, G_8)
* 2 = 3 bpp, aligned (e.g. 888)
* 3 = 4 bpp, aligned (e.g. 8888)
* 4-6 = 2 bpp, not aligned (e.g. 565, 4444, 5551)
* 7 = undefined yuv
* 9 = 2 bpp, aligned
* 10 = undefined
* 11 = undefined
* 12 = 3 bpp, not aligned
* 13 = 4 bpp, not aligned (e.g. 2101010)
* 14-15 = undefined
*/
int
_cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format)
{
size_t 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].bpp;
}
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
* _cogl_pixel_format_get_bytes_per_pixel() */
gboolean
_cogl_pixel_format_is_endian_dependant (CoglPixelFormat format)
{
int aligned = -1;
size_t i;
/* NB: currently checking whether the format components are aligned
* or not determines whether the format is endian dependent or not.
* In the future though we might consider adding formats with
* aligned components that are also endian independant. */
for (i = 0; i < G_N_ELEMENTS (format_info_table); i++)
{
if (format_info_table[i].cogl_format == format)
{
aligned = format_info_table[i].aligned;
break;
}
}
g_return_val_if_fail (aligned != -1, FALSE);
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 *
cogl_pixel_format_to_string (CoglPixelFormat format)
{
size_t 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].format_str;
}
g_assert_not_reached ();
}

View File

@@ -0,0 +1,395 @@
/*
* Cogl
*
* A Low Level GPU Graphics and Utilities API
*
* Copyright (C) 2008,2009 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*
*/
#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION)
#error "Only <cogl/cogl.h> can be included directly."
#endif
#ifndef __COGL_PIXEL_FORMAT_H__
#define __COGL_PIXEL_FORMAT_H__
#include <stdint.h>
#include <stddef.h>
#include <cogl/cogl-defines.h>
#include <glib.h>
#include <glib-object.h>
G_BEGIN_DECLS
/**
* SECTION:cogl-pixel-format
* @short_description: Pixel formats supported by Cogl
*
* The pixel format of an image descrbes how the bits of each pixel are
* represented in memory. For example: an image can be laid out as one long
* sequence of pixels, where each pixel is a sequence of 8 bits of Red, Green
* and Blue. The amount of bits that are used can be different for each pixel
* format, as well as the components (for example an Alpha layer to include
* transparency, or non_RGBA).
*
* Other examples of factors that can influence the layout in memory are the
* system's endianness.
*/
#define COGL_A_BIT (1 << 4)
#define COGL_BGR_BIT (1 << 5)
#define COGL_AFIRST_BIT (1 << 6)
#define COGL_PREMULT_BIT (1 << 7)
#define COGL_DEPTH_BIT (1 << 8)
#define COGL_STENCIL_BIT (1 << 9)
/* XXX: Notes to those adding new formats here...
*
* First this diagram outlines how we allocate the 32bits of a
* CoglPixelFormat currently...
*
* 6 bits for flags
* |-----|
* enum unused 4 bits for the bytes-per-pixel
* and component alignment info
* |------| |-------------| |--|
* 00000000 xxxxxxxx xxxxxxSD PFBA0000
* ^ stencil
* ^ depth
* ^ premult
* ^ alpha first
* ^ bgr order
* ^ has alpha
*
* The most awkward part about the formats is how we use the last 4
* bits to encode the bytes per pixel and component alignment
* information. Ideally we should have had 3 bits for the bpp and a
* flag for alignment but we didn't plan for that in advance so we
* instead use a small lookup table to query the bpp and whether the
* components are byte aligned or not.
*
* The mapping is the following (see discussion on bug #660188):
*
* 0 = undefined
* 1, 8 = 1 bpp (e.g. A_8, G_8)
* 2 = 3 bpp, aligned (e.g. 888)
* 3 = 4 bpp, aligned (e.g. 8888)
* 4-6 = 2 bpp, not aligned (e.g. 565, 4444, 5551)
* 7 = YUV: undefined bpp, undefined alignment
* 9 = 2 bpp, aligned
* 10 = depth, aligned (8, 16, 24, 32, 32f)
* 11 = undefined
* 12 = 3 bpp, not aligned
* 13 = 4 bpp, not aligned (e.g. 2101010)
* 14-15 = undefined
*
* Note: the gap at 10-11 is just because we wanted to maintain that
* all non-aligned formats have the third bit set in case that's
* useful later.
*
* Since we don't want to waste bits adding more and more flags, we'd
* like to see most new pixel formats that can't be represented
* uniquely with the existing flags in the least significant byte
* simply be enumerated with sequential values in the most significant
* enum byte.
*
* Note: Cogl avoids exposing any padded XRGB or RGBX formats and
* instead we leave it up to applications to decided whether they
* consider the A component as padding or valid data. We shouldn't
* change this policy without good reasoning.
*
* So to add a new format:
* 1) Use the mapping table above to figure out what to but in
* the lowest nibble.
* 2) OR in the COGL_PREMULT_BIT, COGL_AFIRST_BIT, COGL_A_BIT and
* COGL_BGR_BIT flags as appropriate.
* 3) If the result is not yet unique then also combine with an
* increment of the last sequence number in the most significant
* byte.
*
* The last sequence number used was 0 (i.e. no formats currently need
* a sequence number)
* Update this note whenever a new sequence number is used.
*/
/**
* CoglPixelFormat:
* @COGL_PIXEL_FORMAT_ANY: Any format
* @COGL_PIXEL_FORMAT_A_8: 8 bits alpha mask
* @COGL_PIXEL_FORMAT_RG_88: RG, 16 bits. Note that red-green textures
* are only available if %COGL_FEATURE_ID_TEXTURE_RG is advertised.
* See cogl_texture_set_components() for details.
* @COGL_PIXEL_FORMAT_RGB_565: RGB, 16 bits
* @COGL_PIXEL_FORMAT_RGBA_4444: RGBA, 16 bits
* @COGL_PIXEL_FORMAT_RGBA_5551: RGBA, 16 bits
* @COGL_PIXEL_FORMAT_YUV: Obsolete. See the other YUV-based formats.
* @COGL_PIXEL_FORMAT_G_8: Single luminance component
* @COGL_PIXEL_FORMAT_RGB_888: RGB, 24 bits
* @COGL_PIXEL_FORMAT_BGR_888: BGR, 24 bits
* @COGL_PIXEL_FORMAT_RGBA_8888: RGBA, 32 bits
* @COGL_PIXEL_FORMAT_BGRA_8888: BGRA, 32 bits
* @COGL_PIXEL_FORMAT_ARGB_8888: ARGB, 32 bits
* @COGL_PIXEL_FORMAT_ABGR_8888: ABGR, 32 bits
* @COGL_PIXEL_FORMAT_RGBA_1010102 : RGBA, 32 bits, 10 bpc
* @COGL_PIXEL_FORMAT_BGRA_1010102 : BGRA, 32 bits, 10 bpc
* @COGL_PIXEL_FORMAT_ARGB_2101010 : ARGB, 32 bits, 10 bpc
* @COGL_PIXEL_FORMAT_ABGR_2101010 : ABGR, 32 bits, 10 bpc
* @COGL_PIXEL_FORMAT_RGBA_8888_PRE: Premultiplied RGBA, 32 bits
* @COGL_PIXEL_FORMAT_BGRA_8888_PRE: Premultiplied BGRA, 32 bits
* @COGL_PIXEL_FORMAT_ARGB_8888_PRE: Premultiplied ARGB, 32 bits
* @COGL_PIXEL_FORMAT_ABGR_8888_PRE: Premultiplied ABGR, 32 bits
* @COGL_PIXEL_FORMAT_RGBA_4444_PRE: Premultiplied RGBA, 16 bits
* @COGL_PIXEL_FORMAT_RGBA_5551_PRE: Premultiplied RGBA, 16 bits
* @COGL_PIXEL_FORMAT_RGBA_1010102_PRE: Premultiplied RGBA, 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_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
* component, the order of the components specify the order in
* increasing memory addresses. So for example
* %COGL_PIXEL_FORMAT_RGB_888 would have the red component in the
* lowest address, green in the next address and blue after that
* regardless of the endianness of the system.
*
* For the formats with non byte aligned components the component
* order specifies the order within a 16-bit or 32-bit number from
* most significant bit to least significant. So for
* %COGL_PIXEL_FORMAT_RGB_565, the red component would be in bits
* 11-15, the green component would be in 6-11 and the blue component
* would be in 1-5. Therefore the order in memory depends on the
* endianness of the system.
*
* When uploading a texture %COGL_PIXEL_FORMAT_ANY can be used as the
* internal format. Cogl will try to pick the best format to use
* internally and convert the texture data if necessary.
*
* Since: 0.8
*/
typedef enum /*< prefix=COGL_PIXEL_FORMAT >*/
{
COGL_PIXEL_FORMAT_ANY = 0,
COGL_PIXEL_FORMAT_A_8 = 1 | COGL_A_BIT,
COGL_PIXEL_FORMAT_RGB_565 = 4,
COGL_PIXEL_FORMAT_RGBA_4444 = 5 | COGL_A_BIT,
COGL_PIXEL_FORMAT_RGBA_5551 = 6 | COGL_A_BIT,
COGL_PIXEL_FORMAT_YUV = 7,
COGL_PIXEL_FORMAT_G_8 = 8,
COGL_PIXEL_FORMAT_RG_88 = 9,
COGL_PIXEL_FORMAT_RGB_888 = 2,
COGL_PIXEL_FORMAT_BGR_888 = (2 | COGL_BGR_BIT),
COGL_PIXEL_FORMAT_RGBA_8888 = (3 | COGL_A_BIT),
COGL_PIXEL_FORMAT_BGRA_8888 = (3 | COGL_A_BIT | COGL_BGR_BIT),
COGL_PIXEL_FORMAT_ARGB_8888 = (3 | COGL_A_BIT | COGL_AFIRST_BIT),
COGL_PIXEL_FORMAT_ABGR_8888 = (3 | COGL_A_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT),
COGL_PIXEL_FORMAT_RGBA_1010102 = (13 | COGL_A_BIT),
COGL_PIXEL_FORMAT_BGRA_1010102 = (13 | COGL_A_BIT | COGL_BGR_BIT),
COGL_PIXEL_FORMAT_ARGB_2101010 = (13 | COGL_A_BIT | COGL_AFIRST_BIT),
COGL_PIXEL_FORMAT_ABGR_2101010 = (13 | COGL_A_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT),
COGL_PIXEL_FORMAT_RGBA_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT),
COGL_PIXEL_FORMAT_BGRA_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT),
COGL_PIXEL_FORMAT_ARGB_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_AFIRST_BIT),
COGL_PIXEL_FORMAT_ABGR_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT),
COGL_PIXEL_FORMAT_RGBA_4444_PRE = (COGL_PIXEL_FORMAT_RGBA_4444 | COGL_A_BIT | COGL_PREMULT_BIT),
COGL_PIXEL_FORMAT_RGBA_5551_PRE = (COGL_PIXEL_FORMAT_RGBA_5551 | COGL_A_BIT | COGL_PREMULT_BIT),
COGL_PIXEL_FORMAT_RGBA_1010102_PRE = (COGL_PIXEL_FORMAT_RGBA_1010102 | COGL_PREMULT_BIT),
COGL_PIXEL_FORMAT_BGRA_1010102_PRE = (COGL_PIXEL_FORMAT_BGRA_1010102 | COGL_PREMULT_BIT),
COGL_PIXEL_FORMAT_ARGB_2101010_PRE = (COGL_PIXEL_FORMAT_ARGB_2101010 | COGL_PREMULT_BIT),
COGL_PIXEL_FORMAT_ABGR_2101010_PRE = (COGL_PIXEL_FORMAT_ABGR_2101010 | COGL_PREMULT_BIT),
COGL_PIXEL_FORMAT_DEPTH_16 = (9 | 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),
/* 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;
/*
* _cogl_pixel_format_get_bytes_per_pixel:
* @format: a #CoglPixelFormat
*
* Queries how many bytes a pixel of the given @format takes.
*
* Return value: The number of bytes taken for a pixel of the given
* @format.
*/
int
_cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format);
/*
* _cogl_pixel_format_has_aligned_components:
* @format: a #CoglPixelFormat
*
* Queries whether the ordering of the components for the given
* @format depend on the endianness of the host CPU or if the
* components can be accessed using bit shifting and bitmasking by
* loading a whole pixel into a word.
*
* XXX: If we ever consider making something like this public we
* should really try to think of a better name and come up with
* much clearer documentation since it really depends on what
* point of view you consider this from whether a format like
* COGL_PIXEL_FORMAT_RGBA_8888 is endian dependent. E.g. If you
* read an RGBA_8888 pixel into a uint32
* it's endian dependent how you mask out the different channels.
* But If you already have separate color components and you want
* to write them to an RGBA_8888 pixel then the bytes can be
* written sequentially regardless of the endianness.
*
* Return value: %TRUE if you need to consider the host CPU
* endianness when dealing with the given @format
* else %FALSE.
*/
gboolean
_cogl_pixel_format_is_endian_dependant (CoglPixelFormat format);
/*
* COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT(format):
* @format: a #CoglPixelFormat
*
* Returns TRUE if the pixel format can take a premult bit. This is
* currently true for all formats that have an alpha channel except
* COGL_PIXEL_FORMAT_A_8 (because that doesn't have any other
* components to multiply by the alpha).
*/
#define COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT(format) \
(((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:
* @format: a #CoglPixelFormat
*
* Returns a string representation of @format, useful for debugging purposes.
*
* Returns: (transfer none): A string representation of @format.
*/
const char *
cogl_pixel_format_to_string (CoglPixelFormat format);
G_END_DECLS
#endif /* __COGL_PIXEL_FORMAT_H__ */

View File

@@ -116,57 +116,6 @@ _cogl_get_enable_legacy_state (void);
#define _cogl_has_private_feature(ctx, feature) \
COGL_FLAGS_GET ((ctx)->private_features, (feature))
/*
* _cogl_pixel_format_get_bytes_per_pixel:
* @format: a #CoglPixelFormat
*
* Queries how many bytes a pixel of the given @format takes.
*
* Return value: The number of bytes taken for a pixel of the given
* @format.
*/
int
_cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format);
/*
* _cogl_pixel_format_has_aligned_components:
* @format: a #CoglPixelFormat
*
* Queries whether the ordering of the components for the given
* @format depend on the endianness of the host CPU or if the
* components can be accessed using bit shifting and bitmasking by
* loading a whole pixel into a word.
*
* XXX: If we ever consider making something like this public we
* should really try to think of a better name and come up with
* much clearer documentation since it really depends on what
* point of view you consider this from whether a format like
* COGL_PIXEL_FORMAT_RGBA_8888 is endian dependent. E.g. If you
* read an RGBA_8888 pixel into a uint32
* it's endian dependent how you mask out the different channels.
* But If you already have separate color components and you want
* to write them to an RGBA_8888 pixel then the bytes can be
* written sequentially regardless of the endianness.
*
* Return value: %TRUE if you need to consider the host CPU
* endianness when dealing with the given @format
* else %FALSE.
*/
gboolean
_cogl_pixel_format_is_endian_dependant (CoglPixelFormat format);
/*
* COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT(format):
* @format: a #CoglPixelFormat
*
* Returns TRUE if the pixel format can take a premult bit. This is
* currently true for all formats that have an alpha channel except
* COGL_PIXEL_FORMAT_A_8 (because that doesn't have any other
* components to multiply by the alpha).
*/
#define COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT(format) \
(((format) & COGL_A_BIT) && (format) != COGL_PIXEL_FORMAT_A_8)
G_END_DECLS
#endif /* __COGL_PRIVATE_H__ */

View File

@@ -53,6 +53,7 @@ typedef struct _CoglTexture CoglTexture;
#include <cogl/cogl-macros.h>
#include <cogl/cogl-defines.h>
#include <cogl/cogl-pixel-buffer.h>
#include <cogl/cogl-pixel-format.h>
#include <cogl/cogl-bitmap.h>
#include <glib-object.h>

View File

@@ -147,172 +147,6 @@ typedef struct _CoglTextureVertex CoglTextureVertex;
#define COGL_DEPTH_BIT (1 << 8)
#define COGL_STENCIL_BIT (1 << 9)
/* XXX: Notes to those adding new formats here...
*
* First this diagram outlines how we allocate the 32bits of a
* CoglPixelFormat currently...
*
* 6 bits for flags
* |-----|
* enum unused 4 bits for the bytes-per-pixel
* and component alignment info
* |------| |-------------| |--|
* 00000000 xxxxxxxx xxxxxxSD PFBA0000
* ^ stencil
* ^ depth
* ^ premult
* ^ alpha first
* ^ bgr order
* ^ has alpha
*
* The most awkward part about the formats is how we use the last 4
* bits to encode the bytes per pixel and component alignment
* information. Ideally we should have had 3 bits for the bpp and a
* flag for alignment but we didn't plan for that in advance so we
* instead use a small lookup table to query the bpp and whether the
* components are byte aligned or not.
*
* The mapping is the following (see discussion on bug #660188):
*
* 0 = undefined
* 1, 8 = 1 bpp (e.g. A_8, G_8)
* 2 = 3 bpp, aligned (e.g. 888)
* 3 = 4 bpp, aligned (e.g. 8888)
* 4-6 = 2 bpp, not aligned (e.g. 565, 4444, 5551)
* 7 = YUV: undefined bpp, undefined alignment
* 9 = 2 bpp, aligned
* 10 = depth, aligned (8, 16, 24, 32, 32f)
* 11 = undefined
* 12 = 3 bpp, not aligned
* 13 = 4 bpp, not aligned (e.g. 2101010)
* 14-15 = undefined
*
* Note: the gap at 10-11 is just because we wanted to maintain that
* all non-aligned formats have the third bit set in case that's
* useful later.
*
* Since we don't want to waste bits adding more and more flags, we'd
* like to see most new pixel formats that can't be represented
* uniquely with the existing flags in the least significant byte
* simply be enumerated with sequential values in the most significant
* enum byte.
*
* Note: Cogl avoids exposing any padded XRGB or RGBX formats and
* instead we leave it up to applications to decided whether they
* consider the A component as padding or valid data. We shouldn't
* change this policy without good reasoning.
*
* So to add a new format:
* 1) Use the mapping table above to figure out what to but in
* the lowest nibble.
* 2) OR in the COGL_PREMULT_BIT, COGL_AFIRST_BIT, COGL_A_BIT and
* COGL_BGR_BIT flags as appropriate.
* 3) If the result is not yet unique then also combine with an
* increment of the last sequence number in the most significant
* byte.
*
* The last sequence number used was 0 (i.e. no formats currently need
* a sequence number)
* Update this note whenever a new sequence number is used.
*/
/**
* CoglPixelFormat:
* @COGL_PIXEL_FORMAT_ANY: Any format
* @COGL_PIXEL_FORMAT_A_8: 8 bits alpha mask
* @COGL_PIXEL_FORMAT_RG_88: RG, 16 bits. Note that red-green textures
* are only available if %COGL_FEATURE_ID_TEXTURE_RG is advertised.
* See cogl_texture_set_components() for details.
* @COGL_PIXEL_FORMAT_RGB_565: RGB, 16 bits
* @COGL_PIXEL_FORMAT_RGBA_4444: RGBA, 16 bits
* @COGL_PIXEL_FORMAT_RGBA_5551: RGBA, 16 bits
* @COGL_PIXEL_FORMAT_YUV: Not currently supported
* @COGL_PIXEL_FORMAT_G_8: Single luminance component
* @COGL_PIXEL_FORMAT_RGB_888: RGB, 24 bits
* @COGL_PIXEL_FORMAT_BGR_888: BGR, 24 bits
* @COGL_PIXEL_FORMAT_RGBA_8888: RGBA, 32 bits
* @COGL_PIXEL_FORMAT_BGRA_8888: BGRA, 32 bits
* @COGL_PIXEL_FORMAT_ARGB_8888: ARGB, 32 bits
* @COGL_PIXEL_FORMAT_ABGR_8888: ABGR, 32 bits
* @COGL_PIXEL_FORMAT_RGBA_1010102 : RGBA, 32 bits, 10 bpc
* @COGL_PIXEL_FORMAT_BGRA_1010102 : BGRA, 32 bits, 10 bpc
* @COGL_PIXEL_FORMAT_ARGB_2101010 : ARGB, 32 bits, 10 bpc
* @COGL_PIXEL_FORMAT_ABGR_2101010 : ABGR, 32 bits, 10 bpc
* @COGL_PIXEL_FORMAT_RGBA_8888_PRE: Premultiplied RGBA, 32 bits
* @COGL_PIXEL_FORMAT_BGRA_8888_PRE: Premultiplied BGRA, 32 bits
* @COGL_PIXEL_FORMAT_ARGB_8888_PRE: Premultiplied ARGB, 32 bits
* @COGL_PIXEL_FORMAT_ABGR_8888_PRE: Premultiplied ABGR, 32 bits
* @COGL_PIXEL_FORMAT_RGBA_4444_PRE: Premultiplied RGBA, 16 bits
* @COGL_PIXEL_FORMAT_RGBA_5551_PRE: Premultiplied RGBA, 16 bits
* @COGL_PIXEL_FORMAT_RGBA_1010102_PRE: Premultiplied RGBA, 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_ABGR_2101010_PRE: Premultiplied ABGR, 32 bits, 10 bpc
*
* Pixel formats used by Cogl. For the formats with a byte per
* component, the order of the components specify the order in
* increasing memory addresses. So for example
* %COGL_PIXEL_FORMAT_RGB_888 would have the red component in the
* lowest address, green in the next address and blue after that
* regardless of the endianness of the system.
*
* For the formats with non byte aligned components the component
* order specifies the order within a 16-bit or 32-bit number from
* most significant bit to least significant. So for
* %COGL_PIXEL_FORMAT_RGB_565, the red component would be in bits
* 11-15, the green component would be in 6-11 and the blue component
* would be in 1-5. Therefore the order in memory depends on the
* endianness of the system.
*
* When uploading a texture %COGL_PIXEL_FORMAT_ANY can be used as the
* internal format. Cogl will try to pick the best format to use
* internally and convert the texture data if necessary.
*
* Since: 0.8
*/
typedef enum /*< prefix=COGL_PIXEL_FORMAT >*/
{
COGL_PIXEL_FORMAT_ANY = 0,
COGL_PIXEL_FORMAT_A_8 = 1 | COGL_A_BIT,
COGL_PIXEL_FORMAT_RGB_565 = 4,
COGL_PIXEL_FORMAT_RGBA_4444 = 5 | COGL_A_BIT,
COGL_PIXEL_FORMAT_RGBA_5551 = 6 | COGL_A_BIT,
COGL_PIXEL_FORMAT_YUV = 7,
COGL_PIXEL_FORMAT_G_8 = 8,
COGL_PIXEL_FORMAT_RG_88 = 9,
COGL_PIXEL_FORMAT_RGB_888 = 2,
COGL_PIXEL_FORMAT_BGR_888 = (2 | COGL_BGR_BIT),
COGL_PIXEL_FORMAT_RGBA_8888 = (3 | COGL_A_BIT),
COGL_PIXEL_FORMAT_BGRA_8888 = (3 | COGL_A_BIT | COGL_BGR_BIT),
COGL_PIXEL_FORMAT_ARGB_8888 = (3 | COGL_A_BIT | COGL_AFIRST_BIT),
COGL_PIXEL_FORMAT_ABGR_8888 = (3 | COGL_A_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT),
COGL_PIXEL_FORMAT_RGBA_1010102 = (13 | COGL_A_BIT),
COGL_PIXEL_FORMAT_BGRA_1010102 = (13 | COGL_A_BIT | COGL_BGR_BIT),
COGL_PIXEL_FORMAT_ARGB_2101010 = (13 | COGL_A_BIT | COGL_AFIRST_BIT),
COGL_PIXEL_FORMAT_ABGR_2101010 = (13 | COGL_A_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT),
COGL_PIXEL_FORMAT_RGBA_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT),
COGL_PIXEL_FORMAT_BGRA_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT),
COGL_PIXEL_FORMAT_ARGB_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_AFIRST_BIT),
COGL_PIXEL_FORMAT_ABGR_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT),
COGL_PIXEL_FORMAT_RGBA_4444_PRE = (COGL_PIXEL_FORMAT_RGBA_4444 | COGL_A_BIT | COGL_PREMULT_BIT),
COGL_PIXEL_FORMAT_RGBA_5551_PRE = (COGL_PIXEL_FORMAT_RGBA_5551 | COGL_A_BIT | COGL_PREMULT_BIT),
COGL_PIXEL_FORMAT_RGBA_1010102_PRE = (COGL_PIXEL_FORMAT_RGBA_1010102 | COGL_PREMULT_BIT),
COGL_PIXEL_FORMAT_BGRA_1010102_PRE = (COGL_PIXEL_FORMAT_BGRA_1010102 | COGL_PREMULT_BIT),
COGL_PIXEL_FORMAT_ARGB_2101010_PRE = (COGL_PIXEL_FORMAT_ARGB_2101010 | COGL_PREMULT_BIT),
COGL_PIXEL_FORMAT_ABGR_2101010_PRE = (COGL_PIXEL_FORMAT_ABGR_2101010 | COGL_PREMULT_BIT),
COGL_PIXEL_FORMAT_DEPTH_16 = (9 | 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)
} CoglPixelFormat;
/**
* CoglFeatureFlags:
* @COGL_FEATURE_TEXTURE_RECTANGLE: ARB_texture_rectangle support

View File

@@ -35,6 +35,7 @@
#include <math.h>
#include <cogl/cogl-defines.h>
#include <cogl/cogl-pixel-format.h>
#include "cogl-types.h"
#include <stdio.h>

View File

@@ -764,55 +764,3 @@ _cogl_init (void)
initialized = TRUE;
}
}
/*
* Returns the number of bytes-per-pixel of a given format. The bpp
* can be extracted from the least significant nibble of the pixel
* format (see CoglPixelFormat).
*
* The mapping is the following (see discussion on bug #660188):
*
* 0 = undefined
* 1, 8 = 1 bpp (e.g. A_8, G_8)
* 2 = 3 bpp, aligned (e.g. 888)
* 3 = 4 bpp, aligned (e.g. 8888)
* 4-6 = 2 bpp, not aligned (e.g. 565, 4444, 5551)
* 7 = undefined yuv
* 9 = 2 bpp, aligned
* 10 = undefined
* 11 = undefined
* 12 = 3 bpp, not aligned
* 13 = 4 bpp, not aligned (e.g. 2101010)
* 14-15 = undefined
*/
int
_cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format)
{
int bpp_lut[] = { 0, 1, 3, 4,
2, 2, 2, 0,
1, 2, 0, 0,
3, 4, 0, 0 };
return bpp_lut [format & 0xf];
}
/* Note: this also refers to the mapping defined above for
* _cogl_pixel_format_get_bytes_per_pixel() */
gboolean
_cogl_pixel_format_is_endian_dependant (CoglPixelFormat format)
{
int aligned_lut[] = { -1, 1, 1, 1,
0, 0, 0, -1,
1, 1, -1, -1,
0, 0, -1, -1};
int aligned = aligned_lut[format & 0xf];
_COGL_RETURN_VAL_IF_FAIL (aligned != -1, FALSE);
/* NB: currently checking whether the format components are aligned
* or not determines whether the format is endian dependent or not.
* In the future though we might consider adding formats with
* aligned components that are also endian independant. */
return aligned;
}

View File

@@ -61,9 +61,11 @@
#include <cogl/cogl1-context.h>
#include <cogl/cogl-bitmap.h>
#include <cogl/cogl-color.h>
#include <cogl/cogl-pixel-format-conversion.h>
#include <cogl/cogl-matrix.h>
#include <cogl/cogl-matrix-stack.h>
#include <cogl/cogl-offscreen.h>
#include <cogl/cogl-pixel-format.h>
#include <cogl/cogl-primitives.h>
#include <cogl/cogl-texture.h>
#include <cogl/cogl-types.h>
@@ -111,6 +113,7 @@
#include <cogl/cogl-sub-texture.h>
#include <cogl/cogl-atlas-texture.h>
#include <cogl/cogl-meta-texture.h>
#include <cogl/cogl-multi-plane-texture.h>
#include <cogl/cogl-primitive-texture.h>
#include <cogl/cogl-index-buffer.h>
#include <cogl/cogl-attribute-buffer.h>

View File

@@ -209,6 +209,8 @@ allocate_from_bitmap (CoglTexture2D *tex_2d,
GLenum gl_format;
GLenum gl_type;
g_warning ("allocate_from_bitmap()");
internal_format =
_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;
GLenum gl_int_format = 0;
g_warning ("allocate_from_egl_image_foreign()");
if (!ctx->texture_driver->allows_foreign_gl_target (ctx, GL_TEXTURE_2D))
{
_cogl_set_error (error,

View File

@@ -268,7 +268,37 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
break;
case COGL_PIXEL_FORMAT_ANY:
/* No support for YUV or multi-plane formats */
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 ();
break;
}

View File

@@ -210,6 +210,8 @@ _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx,
int level_width;
int level_height;
g_warning ("uploading subregion to gl");
cogl_texture_get_gl_texture (texture, &gl_handle, &gl_target);
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;
CoglError *internal_error = NULL;
g_warning ("uploading to gl");
data = _cogl_bitmap_gl_bind (source_bmp,
COGL_BUFFER_ACCESS_READ,
0, /* hints */

View File

@@ -198,7 +198,37 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
break;
case COGL_PIXEL_FORMAT_ANY:
/* No support for YUV or multi-plane formats */
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 ();
break;
}

View File

@@ -88,6 +88,8 @@ cogl_headers = [
'cogl-pipeline.h',
'cogl-pipeline-state.h',
'cogl-pipeline-layer-state.h',
'cogl-pixel-format.h',
'cogl-pixel-format-conversion.h',
'cogl-primitives.h',
'cogl-texture.h',
'cogl-texture-2d.h',
@@ -125,6 +127,7 @@ cogl_nonintrospected_headers = [
'cogl-sub-texture.h',
'cogl-atlas-texture.h',
'cogl-meta-texture.h',
'cogl-multi-plane-texture.h',
'cogl-primitive-texture.h',
'cogl-depth-state.h',
'cogl-buffer.h',
@@ -235,6 +238,7 @@ cogl_sources = [
'cogl-display.c',
'cogl-driver.h',
'cogl.c',
'cogl-pixel-format.c',
'cogl-object-private.h',
'cogl-object.h',
'cogl-object.c',
@@ -250,10 +254,11 @@ cogl_sources = [
'cogl-bitmap-pixbuf.c',
'cogl-clip-stack.h',
'cogl-clip-stack.c',
'cogl-feature-private.h',
'cogl-feature-private.c',
'cogl-color-private.h',
'cogl-color.c',
'cogl-pixel-format-conversion.c',
'cogl-feature-private.c',
'cogl-feature-private.h',
'cogl-buffer-private.h',
'cogl-buffer.c',
'cogl-pixel-buffer-private.h',
@@ -323,6 +328,7 @@ cogl_sources = [
'cogl-atlas-texture-private.h',
'cogl-atlas-texture.c',
'cogl-meta-texture.c',
'cogl-multi-plane-texture.c',
'cogl-primitive-texture.c',
'cogl-blit.h',
'cogl-blit.c',

View File

@@ -1,5 +1,5 @@
project('mutter', 'c',
version: '3.32.1',
version: '3.32.2',
meson_version: '>= 0.48.0',
license: 'GPLv2+'
)

View File

@@ -316,11 +316,18 @@ idle_monitor_dispatch_timeout (GSource *source,
gpointer user_data)
{
MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) user_data;
int64_t now;
int64_t ready_time;
now = g_source_get_time (source);
ready_time = g_source_get_ready_time (source);
if (ready_time > now)
return G_SOURCE_CONTINUE;
_meta_idle_monitor_watch_fire (watch);
g_source_set_ready_time (watch->timeout_source, -1);
return TRUE;
return G_SOURCE_CONTINUE;
}
static GSourceFuncs idle_monitor_source_funcs = {

View File

@@ -381,7 +381,7 @@ guess_candidates (MetaInputMapper *mapper,
info->candidates[META_MATCH_SIZE] = matched_monitor;
}
if (input->builtin)
if (input->builtin || best == N_OUTPUT_MATCHES)
{
best = MIN (best, META_MATCH_IS_BUILTIN);
find_builtin_output (mapper, &info->candidates[META_MATCH_IS_BUILTIN]);

View File

@@ -1216,7 +1216,7 @@ load_keyboard_a11y_settings (MetaInputSettings *input_settings,
ClutterInputDevice *device)
{
MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (input_settings);
ClutterKbdA11ySettings kbd_a11y_settings;
ClutterKbdA11ySettings kbd_a11y_settings = { 0 };
ClutterInputDevice *core_keyboard;
guint i;

View File

@@ -823,6 +823,7 @@ static void
cursor_priv_free (MetaCursorNativePrivate *cursor_priv)
{
g_hash_table_destroy (cursor_priv->gpu_states);
g_free (cursor_priv);
}
static MetaCursorNativePrivate *

View File

@@ -18,6 +18,9 @@ struct _MetaCompositor
guint pre_paint_func_id;
guint post_paint_func_id;
guint stage_presented_id;
guint stage_after_paint_id;
gint64 server_time_query_time;
gint64 server_time_offset;

View File

@@ -92,6 +92,10 @@ on_presented (ClutterStage *stage,
ClutterFrameInfo *frame_info,
MetaCompositor *compositor);
static void
on_top_window_actor_destroyed (MetaWindowActor *window_actor,
MetaCompositor *compositor);
static gboolean
is_modal (MetaDisplay *display)
{
@@ -131,9 +135,31 @@ meta_switch_workspace_completed (MetaCompositor *compositor)
void
meta_compositor_destroy (MetaCompositor *compositor)
{
g_signal_handler_disconnect (compositor->stage,
compositor->stage_after_paint_id);
g_signal_handler_disconnect (compositor->stage,
compositor->stage_presented_id);
compositor->stage_after_paint_id = 0;
compositor->stage_presented_id = 0;
compositor->stage = NULL;
clutter_threads_remove_repaint_func (compositor->pre_paint_func_id);
clutter_threads_remove_repaint_func (compositor->post_paint_func_id);
if (compositor->top_window_actor)
{
g_signal_handlers_disconnect_by_func (compositor->top_window_actor,
on_top_window_actor_destroyed,
compositor);
compositor->top_window_actor = NULL;
}
g_clear_pointer (&compositor->window_group, clutter_actor_destroy);
g_clear_pointer (&compositor->top_window_group, clutter_actor_destroy);
g_clear_pointer (&compositor->feedback_group, clutter_actor_destroy);
g_clear_pointer (&compositor->windows, g_list_free);
if (compositor->have_x11_sync_object)
meta_sync_ring_destroy ();
}
@@ -503,9 +529,10 @@ meta_compositor_manage (MetaCompositor *compositor)
compositor->stage = meta_backend_get_stage (backend);
g_signal_connect (compositor->stage, "presented",
G_CALLBACK (on_presented),
compositor);
compositor->stage_presented_id =
g_signal_connect (compositor->stage, "presented",
G_CALLBACK (on_presented),
compositor);
/* We use connect_after() here to accomodate code in GNOME Shell that,
* when benchmarking drawing performance, connects to ::after-paint
@@ -515,8 +542,9 @@ meta_compositor_manage (MetaCompositor *compositor)
* connections to ::after-paint, connect() vs. connect_after() doesn't
* matter.
*/
g_signal_connect_after (CLUTTER_STAGE (compositor->stage), "after-paint",
G_CALLBACK (after_stage_paint), compositor);
compositor->stage_after_paint_id =
g_signal_connect_after (compositor->stage, "after-paint",
G_CALLBACK (after_stage_paint), compositor);
clutter_stage_set_sync_delay (CLUTTER_STAGE (compositor->stage), META_SYNC_DELAY);

View File

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

View File

@@ -89,7 +89,7 @@ struct _MetaShapedTexture
MetaTextureTower *paint_tower;
CoglTexture *texture;
CoglMultiPlaneTexture *texture;
CoglTexture *mask_texture;
CoglSnippet *snippet;
@@ -97,6 +97,8 @@ struct _MetaShapedTexture
CoglPipeline *masked_pipeline;
CoglPipeline *unblended_pipeline;
CoglPixelFormatConversion *pixel_format_conversion;
gboolean is_y_inverted;
/* The region containing only fully opaque pixels */
@@ -277,9 +279,11 @@ set_clip_region (MetaShapedTexture *stex,
static void
meta_shaped_texture_reset_pipelines (MetaShapedTexture *stex)
{
g_clear_pointer (&stex->base_pipeline, cogl_object_unref);
g_clear_pointer (&stex->masked_pipeline, cogl_object_unref);
g_clear_pointer (&stex->unblended_pipeline, cogl_object_unref);
g_warning ("resetting pipelines!");
cogl_clear_object (&stex->base_pipeline);
cogl_clear_object (&stex->masked_pipeline);
cogl_clear_object (&stex->unblended_pipeline);
}
static void
@@ -297,7 +301,8 @@ meta_shaped_texture_dispose (GObject *object)
meta_texture_tower_free (stex->paint_tower);
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);
meta_shaped_texture_set_mask_texture (stex, NULL);
@@ -306,7 +311,7 @@ meta_shaped_texture_dispose (GObject *object)
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);
}
@@ -316,19 +321,26 @@ get_base_pipeline (MetaShapedTexture *stex,
CoglContext *ctx)
{
CoglPipeline *pipeline;
CoglMatrix matrix;
guint n_planes;
guint i = 0;
if (stex->base_pipeline)
return stex->base_pipeline;
pipeline = cogl_pipeline_new (ctx);
cogl_pipeline_set_layer_wrap_mode_s (pipeline, 0,
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
cogl_pipeline_set_layer_wrap_mode_t (pipeline, 0,
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
cogl_pipeline_set_layer_wrap_mode_s (pipeline, 1,
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
cogl_pipeline_set_layer_wrap_mode_t (pipeline, 1,
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
n_planes = cogl_multi_plane_texture_get_n_planes (stex->texture);
for (i = 0; i < n_planes; i++)
{
cogl_pipeline_set_layer_wrap_mode_s (pipeline, i,
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
cogl_pipeline_set_layer_wrap_mode_t (pipeline, i,
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
}
cogl_matrix_init_identity (&matrix);
if (!stex->is_y_inverted)
{
CoglMatrix matrix;
@@ -378,8 +390,14 @@ get_base_pipeline (MetaShapedTexture *stex,
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)
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;
@@ -398,12 +416,14 @@ get_masked_pipeline (MetaShapedTexture *stex,
CoglContext *ctx)
{
CoglPipeline *pipeline;
gint i, n_layers = 0;
if (stex->masked_pipeline)
return stex->masked_pipeline;
pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
cogl_pipeline_set_layer_combine (pipeline, 1,
n_layers = cogl_multi_plane_texture_get_n_planes (stex->texture);
cogl_pipeline_set_layer_combine (pipeline, n_layers,
"RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
NULL);
@@ -417,17 +437,15 @@ get_unblended_pipeline (MetaShapedTexture *stex,
CoglContext *ctx)
{
CoglPipeline *pipeline;
CoglColor color;
if (stex->unblended_pipeline)
return stex->unblended_pipeline;
pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
cogl_color_init_from_4ub (&color, 255, 255, 255, 255);
cogl_pipeline_set_blend (pipeline,
"RGBA = ADD (SRC_COLOR, 0)",
NULL);
cogl_pipeline_set_color (pipeline, &color);
cogl_pipeline_set_color4ub (pipeline, 255, 255, 255, 255);
stex->unblended_pipeline = pipeline;
@@ -507,23 +525,46 @@ paint_clipped_rectangle (MetaShapedTexture *stex,
}
static void
set_cogl_texture (MetaShapedTexture *stex,
CoglTexture *cogl_tex)
check_texture_color_format (MetaShapedTexture *stex,
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;
g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
if (stex->texture)
cogl_object_unref (stex->texture);
cogl_clear_object (&stex->texture);
stex->texture = planar_tex;
stex->texture = cogl_tex;
if (cogl_tex != NULL)
if (planar_tex != NULL)
{
cogl_object_ref (cogl_tex);
width = cogl_texture_get_width (COGL_TEXTURE (cogl_tex));
height = cogl_texture_get_height (COGL_TEXTURE (cogl_tex));
cogl_object_ref (planar_tex);
width = cogl_multi_plane_texture_get_width (planar_tex);
height = cogl_multi_plane_texture_get_height (planar_tex);
}
else
{
@@ -539,13 +580,22 @@ set_cogl_texture (MetaShapedTexture *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
* know how much of the buffer has changed with respect to the
* previous buffer. We only queue a redraw in response to surface
* damage. */
/* if (FALSE) */
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
@@ -563,10 +613,10 @@ texture_is_idle_and_not_mipmapped (gpointer user_data)
}
static void
do_paint (MetaShapedTexture *stex,
CoglFramebuffer *fb,
CoglTexture *paint_tex,
cairo_region_t *clip_region)
do_paint (MetaShapedTexture *stex,
CoglFramebuffer *fb,
CoglMultiPlaneTexture *paint_tex,
cairo_region_t *clip_region)
{
double tex_scale;
int dst_width, dst_height;
@@ -579,8 +629,12 @@ do_paint (MetaShapedTexture *stex,
CoglContext *ctx;
ClutterActorBox alloc;
CoglPipelineFilter filter;
guint n_planes;
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);
dst_width = stex->dst_width;
@@ -686,8 +740,15 @@ do_paint (MetaShapedTexture *stex,
if (!cairo_region_is_empty (region))
{
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);
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))
{
CoglPipeline *blended_pipeline;
guint i;
if (stex->mask_texture == NULL)
{
@@ -726,16 +788,21 @@ do_paint (MetaShapedTexture *stex,
else
{
blended_pipeline = get_masked_pipeline (stex, ctx);
cogl_pipeline_set_layer_texture (blended_pipeline, 1, stex->mask_texture);
cogl_pipeline_set_layer_filters (blended_pipeline, 1, filter, filter);
cogl_pipeline_set_layer_texture (blended_pipeline, n_planes, stex->mask_texture);
cogl_pipeline_set_layer_filters (blended_pipeline, n_planes, filter, filter);
}
cogl_pipeline_set_layer_texture (blended_pipeline, 0, paint_tex);
cogl_pipeline_set_layer_filters (blended_pipeline, 0, filter, filter);
for (i = 0; i < n_planes; i++)
{
CoglTexture *plane = cogl_multi_plane_texture_get_plane (paint_tex, i);
/* g_warning ("Blended pipeline: adding layer %d, %p", i, plane); */
CoglColor color;
cogl_color_init_from_4ub (&color, opacity, opacity, opacity, opacity);
cogl_pipeline_set_color (blended_pipeline, &color);
cogl_pipeline_set_layer_texture (blended_pipeline, i, plane);
cogl_pipeline_set_layer_filters (blended_pipeline, i, filter, filter);
}
cogl_pipeline_set_color4ub (blended_pipeline,
opacity, opacity, opacity, opacity);
if (blended_tex_region)
{
@@ -778,7 +845,7 @@ static void
meta_shaped_texture_paint (ClutterActor *actor)
{
MetaShapedTexture *stex = META_SHAPED_TEXTURE (actor);
CoglTexture *paint_tex;
CoglMultiPlaneTexture *paint_tex;
CoglFramebuffer *fb;
if (!stex->texture)
@@ -806,6 +873,7 @@ meta_shaped_texture_paint (ClutterActor *actor)
* support for TFP textures will result in fallbacks to XGetImage.
*/
if (stex->create_mipmaps)
/* if (FALSE) */
{
int64_t now = g_get_monotonic_time ();
int64_t age = now - stex->last_invalidation;
@@ -833,11 +901,11 @@ meta_shaped_texture_paint (ClutterActor *actor)
}
else
{
paint_tex = COGL_TEXTURE (stex->texture);
paint_tex = stex->texture;
}
if (cogl_texture_get_width (paint_tex) == 0 ||
cogl_texture_get_height (paint_tex) == 0)
if (cogl_multi_plane_texture_get_width (paint_tex) == 0 ||
cogl_multi_plane_texture_get_height (paint_tex) == 0)
return;
fb = cogl_get_draw_framebuffer ();
@@ -911,7 +979,7 @@ meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex,
if (create_mipmaps != stex->create_mipmaps)
{
CoglTexture *base_texture;
CoglMultiPlaneTexture *base_texture;
stex->create_mipmaps = create_mipmaps;
base_texture = create_mipmaps ? stex->texture : NULL;
meta_texture_tower_set_base_texture (stex->paint_tower, base_texture);
@@ -1094,15 +1162,15 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
/**
* meta_shaped_texture_set_texture:
* @stex: The #MetaShapedTexture
* @pixmap: The #CoglTexture to display
* @pixmap: The #CoglMultiPlaneTexture to display
*/
void
meta_shaped_texture_set_texture (MetaShapedTexture *stex,
CoglTexture *texture)
CoglMultiPlaneTexture *texture)
{
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);
g_clear_pointer (&stex->snippet, cogl_object_unref);
cogl_clear_object (&stex->snippet);
if (snippet)
stex->snippet = cogl_object_ref (snippet);
}
@@ -1143,11 +1211,12 @@ meta_shaped_texture_set_snippet (MetaShapedTexture *stex,
*
* Returns: (transfer none): the unshaped texture
*/
CoglTexture *
CoglMultiPlaneTexture *
meta_shaped_texture_get_texture (MetaShapedTexture *stex)
{
g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), NULL);
return COGL_TEXTURE (stex->texture);
return stex->texture;
}
/**
@@ -1244,7 +1313,15 @@ meta_shaped_texture_reset_viewport_dst_size (MetaShapedTexture *stex)
static gboolean
should_get_via_offscreen (MetaShapedTexture *stex)
{
if (!cogl_texture_is_get_data_supported (stex->texture))
CoglTexture *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;
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
* cairo_surface_destroy().
*/
/* XXX Still need to fix this, but apparently only used for screenshot */
cairo_surface_t *
meta_shaped_texture_get_image (MetaShapedTexture *stex,
cairo_rectangle_int_t *clip)
{
cairo_rectangle_int_t *transformed_clip = NULL;
CoglTexture *texture, *mask_texture;
CoglTexture *texture;
CoglTexture *mask_texture;
cairo_surface_t *surface;
g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), NULL);
texture = COGL_TEXTURE (stex->texture);
if (texture == NULL)
if (stex->texture == NULL)
return NULL;
ensure_size_valid (stex);
@@ -1406,6 +1483,9 @@ meta_shaped_texture_get_image (MetaShapedTexture *stex,
if (should_get_via_offscreen (stex))
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)
texture = cogl_texture_new_from_sub_texture (texture,
transformed_clip->x,

View File

@@ -45,7 +45,7 @@ struct _MetaSurfaceActorX11
MetaDisplay *display;
CoglTexture *texture;
CoglMultiPlaneTexture *texture;
Pixmap pixmap;
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))))
g_warning ("NOTE: Not using GLX TFP!\n");
self->texture = texture;
meta_shaped_texture_set_texture (stex, texture);
/* FIXME: we need to find out the format here */
self->texture = cogl_multi_plane_texture_new_single_plane (COGL_PIXEL_FORMAT_ANY, texture);
meta_shaped_texture_set_texture (stex, self->texture);
}
static void
@@ -187,6 +188,7 @@ meta_surface_actor_x11_process_damage (MetaSurfaceActor *actor,
int x, int y, int width, int height)
{
MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor);
CoglTexture *texture;
self->received_damage = TRUE;
@@ -210,7 +212,8 @@ meta_surface_actor_x11_process_damage (MetaSurfaceActor *actor,
if (!is_visible (self))
return;
cogl_texture_pixmap_x11_update_area (COGL_TEXTURE_PIXMAP_X11 (self->texture),
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);
}

View File

@@ -325,7 +325,8 @@ gboolean
meta_surface_actor_is_argb32 (MetaSurfaceActor *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
* that we're ARGB32.
@@ -335,9 +336,14 @@ meta_surface_actor_is_argb32 (MetaSurfaceActor *self)
* place. This prevents us from continually redirecting and
* unredirecting on every paint.
*/
if (!texture)
if (!mtex)
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))
{
case COGL_TEXTURE_COMPONENTS_A:

View File

@@ -59,8 +59,8 @@ typedef struct
struct _MetaTextureTower
{
int n_levels;
CoglTexture *textures[MAX_TEXTURE_LEVELS];
CoglOffscreen *fbos[MAX_TEXTURE_LEVELS];
CoglMultiPlaneTexture *textures[MAX_TEXTURE_LEVELS];
GList *fbos[MAX_TEXTURE_LEVELS];
Box invalid[MAX_TEXTURE_LEVELS];
CoglPipeline *pipeline_template;
};
@@ -113,8 +113,8 @@ meta_texture_tower_free (MetaTextureTower *tower)
* unset or until the tower is freed.
*/
void
meta_texture_tower_set_base_texture (MetaTextureTower *tower,
CoglTexture *texture)
meta_texture_tower_set_base_texture (MetaTextureTower *tower,
CoglMultiPlaneTexture *texture)
{
int i;
@@ -127,22 +127,14 @@ meta_texture_tower_set_base_texture (MetaTextureTower *tower,
{
for (i = 1; i < tower->n_levels; i++)
{
if (tower->textures[i] != NULL)
{
cogl_object_unref (tower->textures[i]);
tower->textures[i] = NULL;
}
cogl_clear_object (&tower->textures[i]);
if (tower->fbos[i] != NULL)
{
cogl_object_unref (tower->fbos[i]);
tower->fbos[i] = NULL;
}
g_list_free_full (tower->fbos[i], cogl_object_unref);
tower->fbos[i] = NULL;
}
cogl_object_unref (tower->textures[0]);
}
cogl_clear_object (&tower->textures[0]);
tower->textures[0] = texture;
if (tower->textures[0] != NULL)
@@ -151,8 +143,8 @@ meta_texture_tower_set_base_texture (MetaTextureTower *tower,
cogl_object_ref (tower->textures[0]);
width = cogl_texture_get_width (tower->textures[0]);
height = cogl_texture_get_height (tower->textures[0]);
width = cogl_multi_plane_texture_get_width (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 = MIN(tower->n_levels, MAX_TEXTURE_LEVELS);
@@ -193,8 +185,8 @@ meta_texture_tower_update_area (MetaTextureTower *tower,
if (tower->textures[0] == NULL)
return;
texture_width = cogl_texture_get_width (tower->textures[0]);
texture_height = cogl_texture_get_height (tower->textures[0]);
texture_width = cogl_multi_plane_texture_get_width (tower->textures[0]);
texture_height = cogl_multi_plane_texture_get_height (tower->textures[0]);
invalid.x1 = x;
invalid.y1 = y;
@@ -358,23 +350,28 @@ texture_tower_create_texture (MetaTextureTower *tower,
int width,
int height)
{
if ((!is_power_of_two (width) || !is_power_of_two (height)) &&
meta_texture_rectangle_check (tower->textures[level - 1]))
{
ClutterBackend *backend = clutter_get_default_backend ();
CoglContext *context = clutter_backend_get_cogl_context (backend);
CoglTextureRectangle *texture_rectangle;
CoglMultiPlaneTexture *base_tex = tower->textures[0];
GPtrArray *planes;
guint n_planes, i;
texture_rectangle = cogl_texture_rectangle_new_with_size (context, width, height);
tower->textures[level] = COGL_TEXTURE (texture_rectangle);
}
else
n_planes = cogl_multi_plane_texture_get_n_planes (base_tex);
planes = g_ptr_array_new_full (n_planes, cogl_object_unref);
for (i = 0; i < n_planes; i++)
{
tower->textures[level] = cogl_texture_new_with_size (width, height,
COGL_TEXTURE_NO_AUTO_MIPMAP,
TEXTURE_FORMAT);
CoglTexture *texture;
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].y1 = 0;
tower->invalid[level].x2 = width;
@@ -385,51 +382,69 @@ static void
texture_tower_revalidate (MetaTextureTower *tower,
int level)
{
CoglTexture *source_texture = tower->textures[level - 1];
int source_texture_width = cogl_texture_get_width (source_texture);
int source_texture_height = cogl_texture_get_height (source_texture);
CoglTexture *dest_texture = tower->textures[level];
int dest_texture_width = cogl_texture_get_width (dest_texture);
int dest_texture_height = cogl_texture_get_height (dest_texture);
Box *invalid = &tower->invalid[level];
CoglFramebuffer *fb;
CoglError *catch_error = NULL;
CoglPipeline *pipeline;
CoglMultiPlaneTexture *src_tex = tower->textures[level - 1];
int src_width = cogl_multi_plane_texture_get_width (src_tex);
int src_height = cogl_multi_plane_texture_get_height (src_tex);
guint src_tex_n_planes = cogl_multi_plane_texture_get_n_planes (src_tex);
CoglMultiPlaneTexture *dest_tex = tower->textures[level];
int dest_width = cogl_multi_plane_texture_get_width (dest_tex);
int dest_height = cogl_multi_plane_texture_get_height (dest_tex);
guint i;
if (tower->fbos[level] == NULL)
tower->fbos[level] = cogl_offscreen_new_with_texture (dest_texture);
fb = COGL_FRAMEBUFFER (tower->fbos[level]);
if (!cogl_framebuffer_allocate (fb, &catch_error))
/* FIXME: cogl_offscreen_texture_new_with_texture doesn't work for
* multi-plane textures, so we have to make an FBO for each layer */
for (i = 0; i < src_tex_n_planes; i++)
{
cogl_error_free (catch_error);
return;
Box *invalid = &tower->invalid[level];
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].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
* %NULL if no base texture has yet been set.
*/
CoglTexture *
CoglMultiPlaneTexture *
meta_texture_tower_get_paint_texture (MetaTextureTower *tower)
{
int texture_width, texture_height;
@@ -458,8 +473,8 @@ meta_texture_tower_get_paint_texture (MetaTextureTower *tower)
if (tower->textures[0] == NULL)
return NULL;
texture_width = cogl_texture_get_width (tower->textures[0]);
texture_height = cogl_texture_get_height (tower->textures[0]);
texture_width = cogl_multi_plane_texture_get_width (tower->textures[0]);
texture_height = cogl_multi_plane_texture_get_height (tower->textures[0]);
level = get_paint_level(texture_width, texture_height);
if (level < 0) /* singular paint matrix, scaled to nothing */

View File

@@ -53,14 +53,14 @@ typedef struct _MetaTextureTower MetaTextureTower;
MetaTextureTower *meta_texture_tower_new (void);
void meta_texture_tower_free (MetaTextureTower *tower);
void meta_texture_tower_set_base_texture (MetaTextureTower *tower,
CoglTexture *texture);
void meta_texture_tower_set_base_texture (MetaTextureTower *tower,
CoglMultiPlaneTexture *texture);
void meta_texture_tower_update_area (MetaTextureTower *tower,
int x,
int y,
int width,
int height);
CoglTexture *meta_texture_tower_get_paint_texture (MetaTextureTower *tower);
CoglMultiPlaneTexture *meta_texture_tower_get_paint_texture (MetaTextureTower *tower);
G_END_DECLS

View File

@@ -1503,10 +1503,12 @@ build_and_scan_frame_mask (MetaWindowActor *self,
guchar *mask_data;
guint tex_width, tex_height;
MetaShapedTexture *stex;
CoglTexture *paint_tex, *mask_texture;
CoglMultiPlaneTexture *paint_tex;
CoglTexture *mask_texture;
int stride;
cairo_t *cr;
cairo_surface_t *surface;
CoglError *error = NULL;
stex = meta_surface_actor_get_texture (priv->surface);
g_return_if_fail (stex);
@@ -1517,8 +1519,8 @@ build_and_scan_frame_mask (MetaWindowActor *self,
if (paint_tex == NULL)
return;
tex_width = cogl_texture_get_width (paint_tex);
tex_height = cogl_texture_get_height (paint_tex);
tex_width = cogl_multi_plane_texture_get_width (paint_tex);
tex_height = cogl_multi_plane_texture_get_height (paint_tex);
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_surface_destroy (surface);
if (meta_texture_rectangle_check (paint_tex))
{
mask_texture = COGL_TEXTURE (cogl_texture_rectangle_new_with_size (ctx, tex_width, tex_height));
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,
COGL_PIXEL_FORMAT_A_8,
stride, mask_data, &error));
mask_texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (ctx, tex_width, tex_height,
COGL_PIXEL_FORMAT_A_8,
stride, mask_data, &error));
if (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);

View File

@@ -110,13 +110,24 @@ static void
meta_launch_context_constructed (GObject *object)
{
MetaLaunchContext *context = META_LAUNCH_CONTEXT (object);
const char *x11_display, *wayland_display;
G_OBJECT_CLASS (meta_launch_context_parent_class)->constructed (object);
g_app_launch_context_setenv (G_APP_LAUNCH_CONTEXT (context),
"DISPLAY", getenv ("DISPLAY"));
g_app_launch_context_setenv (G_APP_LAUNCH_CONTEXT (context),
"WAYLAND_DISPLAY", getenv ("WAYLAND_DISPLAY"));
x11_display = getenv ("DISPLAY");
wayland_display = getenv ("WAYLAND_DISPLAY");
if (x11_display)
{
g_app_launch_context_setenv (G_APP_LAUNCH_CONTEXT (context),
"DISPLAY", x11_display);
}
if (wayland_display)
{
g_app_launch_context_setenv (G_APP_LAUNCH_CONTEXT (context),
"WAYLAND_DISPLAY", wayland_display);
}
}
static gchar *

View File

@@ -52,7 +52,7 @@ gboolean meta_shaped_texture_update_area (MetaShapedTexture *stex,
int height);
META_EXPORT
CoglTexture * meta_shaped_texture_get_texture (MetaShapedTexture *stex);
CoglMultiPlaneTexture * meta_shaped_texture_get_texture (MetaShapedTexture *stex);
META_EXPORT
void meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,

View File

@@ -123,7 +123,7 @@ meta_wayland_buffer_realize (MetaWaylandBuffer *buffer)
stream = meta_wayland_egl_stream_new (buffer, NULL);
if (stream)
{
CoglTexture2D *texture;
CoglMultiPlaneTexture *texture;
texture = meta_wayland_egl_stream_create_texture (stream, NULL);
if (!texture)
@@ -131,7 +131,7 @@ meta_wayland_buffer_realize (MetaWaylandBuffer *buffer)
buffer->egl_stream.stream = stream;
buffer->type = META_WAYLAND_BUFFER_TYPE_EGL_STREAM;
buffer->egl_stream.texture = COGL_TEXTURE (texture);
buffer->egl_stream.texture = texture;
buffer->is_y_inverted = meta_wayland_egl_stream_is_y_inverted (stream);
return TRUE;
@@ -163,17 +163,18 @@ shm_buffer_get_cogl_pixel_format (struct wl_shm_buffer *shm_buffer,
CoglTextureComponents *components_out)
{
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))
{
#if G_BYTE_ORDER == G_BIG_ENDIAN
case WL_SHM_FORMAT_ARGB8888:
format = COGL_PIXEL_FORMAT_ARGB_8888_PRE;
components_out[0] = COGL_TEXTURE_COMPONENTS_RGBA;
break;
case WL_SHM_FORMAT_XRGB8888:
format = COGL_PIXEL_FORMAT_ARGB_8888;
components = COGL_TEXTURE_COMPONENTS_RGB;
components_out[0] = COGL_TEXTURE_COMPONENTS_RGB;
break;
#elif G_BYTE_ORDER == G_LITTLE_ENDIAN
case WL_SHM_FORMAT_ARGB8888:
@@ -181,25 +182,59 @@ shm_buffer_get_cogl_pixel_format (struct wl_shm_buffer *shm_buffer,
break;
case WL_SHM_FORMAT_XRGB8888:
format = COGL_PIXEL_FORMAT_BGRA_8888;
components = COGL_TEXTURE_COMPONENTS_RGB;
components_out[0] = COGL_TEXTURE_COMPONENTS_RGB;
break;
#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:
g_warn_if_reached ();
format = COGL_PIXEL_FORMAT_ARGB_8888;
components_out[0] = COGL_TEXTURE_COMPONENTS_RGBA;
}
if (format_out)
*format_out = format;
if (components_out)
*components_out = components;
}
static gboolean
shm_buffer_attach (MetaWaylandBuffer *buffer,
CoglTexture **texture,
gboolean *changed_texture,
GError **error)
shm_buffer_attach (MetaWaylandBuffer *buffer,
CoglMultiPlaneTexture **texture,
gboolean *changed_texture,
GError **error)
{
MetaBackend *backend = meta_get_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;
int stride, width, height;
CoglPixelFormat format;
CoglTextureComponents components;
CoglBitmap *bitmap;
CoglTexture *new_texture;
CoglTextureComponents components[3];
guint i, n_planes;
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);
stride = wl_shm_buffer_get_stride (shm_buffer);
width = wl_shm_buffer_get_width (shm_buffer);
height = wl_shm_buffer_get_height (shm_buffer);
shm_buffer_get_cogl_pixel_format (shm_buffer, &format, &components);
shm_buffer_get_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 &&
cogl_texture_get_width (*texture) == width &&
cogl_texture_get_height (*texture) == height &&
cogl_texture_get_components (*texture) == components &&
_cogl_texture_get_format (*texture) == format)
cogl_multi_plane_texture_get_width (*texture) == width &&
cogl_multi_plane_texture_get_height (*texture) == height &&
/*XXX cogl_texture_get_components (*texture) == components && */
cogl_multi_plane_texture_get_format (*texture) == format)
{
buffer->is_y_inverted = TRUE;
*changed_texture = FALSE;
@@ -230,56 +271,57 @@ shm_buffer_attach (MetaWaylandBuffer *buffer,
cogl_clear_object (texture);
/* Safely access the data inside the buffer */
wl_shm_buffer_begin_access (shm_buffer);
data = wl_shm_buffer_get_data (shm_buffer);
bitmap = cogl_bitmap_new_for_data (cogl_context,
width, height,
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))
bitmaps = g_ptr_array_new_full (n_planes, cogl_object_unref);
for (i = 0; i < n_planes; i++)
{
g_clear_pointer (&new_texture, cogl_object_unref);
if (g_error_matches (*error, COGL_TEXTURE_ERROR, COGL_TEXTURE_ERROR_SIZE))
{
CoglTexture2DSliced *texture_sliced;
CoglBitmap *bitmap;
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 =
cogl_texture_2d_sliced_new_from_bitmap (bitmap,
COGL_TEXTURE_MAX_WASTE);
new_texture = COGL_TEXTURE (texture_sliced);
cogl_texture_set_components (new_texture, components);
g_warning ("Creating plane %d, h_factor = %d, v_factor = %d, offset = %lu",
i, h_factors[i], v_factors[i], offset);
if (!cogl_texture_allocate (new_texture, error))
g_clear_pointer (&new_texture, cogl_object_unref);
}
bitmap = cogl_bitmap_new_for_data (cogl_context,
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);
if (!new_texture)
return FALSE;
*texture = new_texture;
*changed_texture = 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;
}
static gboolean
egl_image_buffer_attach (MetaWaylandBuffer *buffer,
CoglTexture **texture,
gboolean *changed_texture,
GError **error)
egl_image_buffer_attach (MetaWaylandBuffer *buffer,
CoglMultiPlaneTexture **texture,
gboolean *changed_texture,
GError **error)
{
MetaBackend *backend = meta_get_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);
int format, width, height, y_inverted;
CoglPixelFormat cogl_format;
EGLImageKHR egl_image;
CoglTexture2D *texture_2d;
guint i, n_planes;
GPtrArray *planes;
if (buffer->egl_image.texture)
{
@@ -299,6 +341,7 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
return TRUE;
}
/* Query the necessary properties */
if (!meta_egl_query_wayland_buffer (egl, egl_display, buffer->resource,
EGL_TEXTURE_FORMAT, &format,
error))
@@ -319,6 +362,7 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
NULL))
y_inverted = EGL_TRUE;
/* Map the EGL texture format to CoglPixelFormat, if possible */
switch (format)
{
case EGL_TEXTURE_RGB:
@@ -327,6 +371,14 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
case EGL_TEXTURE_RGBA:
cogl_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE;
break;
case EGL_TEXTURE_Y_UV_WL:
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:
g_set_error (error, G_IO_ERROR,
G_IO_ERROR_FAILED,
@@ -334,27 +386,49 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
return FALSE;
}
/* The WL_bind_wayland_display spec states that EGL_NO_CONTEXT is to be used
* in conjunction with the EGL_WAYLAND_BUFFER_WL target. */
egl_image = meta_egl_create_image (egl, egl_display, EGL_NO_CONTEXT,
EGL_WAYLAND_BUFFER_WL, buffer->resource,
NULL,
error);
if (egl_image == EGL_NO_IMAGE_KHR)
return FALSE;
n_planes = cogl_pixel_format_get_n_planes (cogl_format);
planes = g_ptr_array_new_full (n_planes, cogl_object_unref);
texture_2d = cogl_egl_texture_2d_new_from_image (cogl_context,
width, height,
cogl_format,
egl_image,
error);
/* Each EGLImage is a plane in the final texture */
for (i = 0; i < n_planes; i++)
{
EGLint egl_attribs[3];
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)
return FALSE;
/* The WL_bind_wayland_display spec states that EGL_NO_CONTEXT is to be
* used in conjunction with the EGL_WAYLAND_BUFFER_WL target. */
egl_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;
cogl_clear_object (texture);
@@ -362,14 +436,19 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
*changed_texture = TRUE;
return TRUE;
on_error:
g_ptr_array_free (planes, TRUE);
return FALSE;
}
#ifdef HAVE_WAYLAND_EGLSTREAM
static gboolean
egl_stream_buffer_attach (MetaWaylandBuffer *buffer,
CoglTexture **texture,
gboolean *changed_texture,
GError **error)
egl_stream_buffer_attach (MetaWaylandBuffer *buffer,
CoglMultiPlaneTexture **texture,
gboolean *changed_texture,
GError **error)
{
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.
*/
gboolean
meta_wayland_buffer_attach (MetaWaylandBuffer *buffer,
CoglTexture **texture,
gboolean *changed_texture,
GError **error)
meta_wayland_buffer_attach (MetaWaylandBuffer *buffer,
CoglMultiPlaneTexture **texture,
gboolean *changed_texture,
GError **error)
{
g_return_val_if_fail (buffer->resource, FALSE);
@@ -425,14 +504,18 @@ meta_wayland_buffer_attach (MetaWaylandBuffer *buffer,
switch (buffer->type)
{
case META_WAYLAND_BUFFER_TYPE_SHM:
g_warning ("GOT SHM BUFFER");
return shm_buffer_attach (buffer, texture, changed_texture, error);
case META_WAYLAND_BUFFER_TYPE_EGL_IMAGE:
g_warning ("GOT EGL IMAGE BUFFER");
return egl_image_buffer_attach (buffer, texture, changed_texture, error);
#ifdef HAVE_WAYLAND_EGLSTREAM
case META_WAYLAND_BUFFER_TYPE_EGL_STREAM:
g_warning ("GOT EGL STREAM BUFFER");
return egl_stream_buffer_attach (buffer, texture, changed_texture, error);
#endif
case META_WAYLAND_BUFFER_TYPE_DMA_BUF:
g_warning ("GOT DMA BUF BUFFER");
return meta_wayland_dma_buf_buffer_attach (buffer,
texture,
changed_texture,
@@ -466,55 +549,84 @@ meta_wayland_buffer_is_y_inverted (MetaWaylandBuffer *buffer)
}
static gboolean
process_shm_buffer_damage (MetaWaylandBuffer *buffer,
CoglTexture *texture,
cairo_region_t *region,
GError **error)
process_shm_buffer_damage (MetaWaylandBuffer *buffer,
CoglMultiPlaneTexture *texture,
cairo_region_t *region,
GError **error)
{
struct wl_shm_buffer *shm_buffer;
int i, n_rectangles;
gint j, n_rectangles;
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);
shm_buffer = wl_shm_buffer_get (buffer->resource);
/* Get the data */
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);
int32_t stride = wl_shm_buffer_get_stride (shm_buffer);
CoglPixelFormat format;
int bpp;
cairo_rectangle_int_t rect;
CoglTexture *plane;
shm_buffer_get_cogl_pixel_format (shm_buffer, &format, NULL);
bpp = _cogl_pixel_format_get_bytes_per_pixel (format);
cairo_region_get_rectangle (region, i, &rect);
plane = cogl_multi_plane_texture_get_plane (texture, i);
if (!_cogl_texture_set_region (texture,
rect.width, rect.height,
format,
stride,
data + rect.x * bpp + rect.y * stride,
rect.x, rect.y,
0,
error))
for (j = 0; j < n_rectangles; j++)
{
set_texture_failed = TRUE;
break;
cairo_rectangle_int_t rect;
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);
return !set_texture_failed;
}
void
meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer,
CoglTexture *texture,
cairo_region_t *region)
meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer,
CoglMultiPlaneTexture *texture,
cairo_region_t *region)
{
gboolean res = FALSE;
GError *error = NULL;

View File

@@ -56,19 +56,19 @@ struct _MetaWaylandBuffer
MetaWaylandBufferType type;
struct {
CoglTexture *texture;
CoglMultiPlaneTexture *texture;
} egl_image;
#ifdef HAVE_WAYLAND_EGLSTREAM
struct {
MetaWaylandEglStream *stream;
CoglTexture *texture;
CoglMultiPlaneTexture *texture;
} egl_stream;
#endif
struct {
MetaWaylandDmaBufBuffer *dma_buf;
CoglTexture *texture;
CoglMultiPlaneTexture *texture;
} 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);
gboolean meta_wayland_buffer_is_realized (MetaWaylandBuffer *buffer);
gboolean meta_wayland_buffer_realize (MetaWaylandBuffer *buffer);
gboolean meta_wayland_buffer_attach (MetaWaylandBuffer *buffer,
CoglTexture **texture,
gboolean *changed_texture,
GError **error);
gboolean meta_wayland_buffer_attach (MetaWaylandBuffer *buffer,
CoglMultiPlaneTexture **texture,
gboolean *changed_texture,
GError **error);
CoglSnippet * meta_wayland_buffer_create_snippet (MetaWaylandBuffer *buffer);
gboolean meta_wayland_buffer_is_y_inverted (MetaWaylandBuffer *buffer);
void meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer,
CoglTexture *texture,
CoglMultiPlaneTexture *texture,
cairo_region_t *region);
#endif /* META_WAYLAND_BUFFER_H */

View File

@@ -58,7 +58,7 @@ update_cursor_sprite_texture (MetaWaylandCursorSurface *cursor_surface)
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (META_WAYLAND_SURFACE_ROLE (cursor_surface));
MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (priv->cursor_sprite);
CoglTexture *texture;
CoglMultiPlaneTexture *texture;
if (!priv->cursor_renderer)
return;
@@ -66,8 +66,13 @@ update_cursor_sprite_texture (MetaWaylandCursorSurface *cursor_surface)
texture = meta_wayland_surface_get_texture (surface);
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,
texture,
plane,
priv->hot_x * surface->scale,
priv->hot_y * surface->scale);
}

View File

@@ -56,8 +56,9 @@ struct _MetaWaylandDmaBufBuffer
int width;
int height;
uint32_t drm_format;
uint64_t drm_modifier;
bool is_y_inverted;
uint64_t drm_modifier[META_WAYLAND_DMA_BUF_MAX_FDS];
int fds[META_WAYLAND_DMA_BUF_MAX_FDS];
int offsets[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);
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
meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer *buffer,
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);
MetaWaylandDmaBufBuffer *dma_buf = buffer->dma_buf.dma_buf;
CoglPixelFormat cogl_format;
EGLImageKHR egl_image;
CoglTexture2D *texture;
EGLint attribs[64];
int attr_idx = 0;
GPtrArray *planes;
guint i = 0, n_planes = 1;
if (buffer->dma_buf.texture)
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))
{
/*
* 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,
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Unsupported buffer format %d", dma_buf->drm_format);
return FALSE;
}
attribs[attr_idx++] = EGL_WIDTH;
attribs[attr_idx++] = dma_buf->width;
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;
n_planes = cogl_pixel_format_get_n_planes (cogl_format);
planes = g_ptr_array_new_full (n_planes, cogl_object_unref);
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 & 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)
/* Each EGLImage is a plane in the final CoglMultiPlaneTexture */
for (i = 0; i < n_planes; i++)
{
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 & 0xffffffff;
attribs[attr_idx++] = EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT;
attribs[attr_idx++] = dma_buf->drm_modifier >> 32;
EGLImageKHR egl_img;
CoglTexture2D *plane;
egl_img = create_egl_image_from_dmabuf (egl,
egl_display,
dma_buf,
dma_buf->width, dma_buf->height,
dma_buf->drm_format,
error);
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)
{
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 & 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->dma_buf.texture = cogl_multi_plane_texture_new (cogl_format,
(CoglTexture **) g_ptr_array_free (planes, FALSE),
n_planes);
buffer->is_y_inverted = dma_buf->is_y_inverted;
return TRUE;
on_error:
g_ptr_array_free (planes, TRUE);
return FALSE;
}
gboolean
meta_wayland_dma_buf_buffer_attach (MetaWaylandBuffer *buffer,
CoglTexture **texture,
gboolean *changed_texture,
GError **error)
meta_wayland_dma_buf_buffer_attach (MetaWaylandBuffer *buffer,
CoglMultiPlaneTexture **texture,
gboolean *changed_texture,
GError **error)
{
if (!meta_wayland_dma_buf_realize_texture (buffer, error))
return FALSE;
@@ -234,7 +303,7 @@ buffer_params_add (struct wl_client *client,
drm_modifier |= ((uint64_t) drm_modifier_lo) & 0xffffffff;
dma_buf = wl_resource_get_user_data (resource);
if (!dma_buf)
if (G_UNLIKELY (!dma_buf))
{
wl_resource_post_error (resource,
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_ALREADY_USED,
@@ -242,7 +311,7 @@ buffer_params_add (struct wl_client *client,
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,
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_IDX,
@@ -251,7 +320,7 @@ buffer_params_add (struct wl_client *client,
return;
}
if (dma_buf->fds[plane_idx] != -1)
if (G_UNLIKELY (dma_buf->fds[plane_idx] != -1))
{
wl_resource_post_error (resource,
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_SET,
@@ -260,8 +329,8 @@ buffer_params_add (struct wl_client *client,
return;
}
if (dma_buf->drm_modifier != DRM_FORMAT_MOD_INVALID &&
dma_buf->drm_modifier != drm_modifier)
if (G_UNLIKELY (dma_buf->drm_modifier[plane_idx] != DRM_FORMAT_MOD_INVALID &&
dma_buf->drm_modifier[plane_idx] != drm_modifier))
{
wl_resource_post_error (resource,
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_WL_BUFFER,
@@ -269,8 +338,9 @@ buffer_params_add (struct wl_client *client,
return;
}
dma_buf->drm_modifier = drm_modifier;
dma_buf->fds[plane_idx] = fd;
dma_buf->drm_modifier[plane_idx] = drm_modifier;
dma_buf->offsets[plane_idx] = offset;
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_ARGB2101010);
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
@@ -598,10 +678,12 @@ meta_wayland_dma_buf_buffer_init (MetaWaylandDmaBufBuffer *dma_buf)
{
int i;
dma_buf->drm_modifier = DRM_FORMAT_MOD_INVALID;
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

View File

@@ -42,10 +42,10 @@ typedef struct _MetaWaylandDmaBufBuffer MetaWaylandDmaBufBuffer;
gboolean meta_wayland_dma_buf_init (MetaWaylandCompositor *compositor);
gboolean
meta_wayland_dma_buf_buffer_attach (MetaWaylandBuffer *buffer,
CoglTexture **texture,
gboolean *changed_texture,
GError **error);
meta_wayland_dma_buf_buffer_attach (MetaWaylandBuffer *buffer,
CoglMultiPlaneTexture **texture,
gboolean *changed_texture,
GError **error);
MetaWaylandDmaBufBuffer *
meta_wayland_dma_buf_from_buffer (MetaWaylandBuffer *buffer);

View File

@@ -132,7 +132,7 @@ struct _MetaWaylandEglStream
EGLStreamKHR egl_stream;
MetaWaylandBuffer *buffer;
CoglTexture2D *texture;
CoglMultiPlaneTexture *texture;
gboolean is_y_inverted;
};
@@ -183,7 +183,7 @@ stream_texture_destroyed (gpointer data)
}
static gboolean
alloc_egl_stream_texture (CoglTexture2D *texture,
alloc_egl_stream_texture (CoglTexture2D *texture_2d,
gpointer user_data,
GError **error)
{
@@ -199,7 +199,7 @@ alloc_egl_stream_texture (CoglTexture2D *texture,
error);
}
CoglTexture2D *
CoglMultiPlaneTexture *
meta_wayland_egl_stream_create_texture (MetaWaylandEglStream *stream,
GError **error)
{
@@ -208,7 +208,7 @@ meta_wayland_egl_stream_create_texture (MetaWaylandEglStream *stream,
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context);
CoglTexture2D *texture;
CoglTexture2D *texture_2d;
int width, height;
int y_inverted;
@@ -230,29 +230,30 @@ meta_wayland_egl_stream_create_texture (MetaWaylandEglStream *stream,
NULL))
y_inverted = EGL_TRUE;
texture =
texture_2d =
cogl_texture_2d_new_from_egl_image_external (cogl_context,
width, height,
alloc_egl_stream_texture,
g_object_ref (stream),
stream_texture_destroyed,
error);
if (!texture)
if (!texture_2d)
{
g_object_unref (stream);
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;
}
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;
return texture;
return stream->texture;
}
gboolean

View File

@@ -45,8 +45,8 @@ MetaWaylandEglStream * meta_wayland_egl_stream_new (MetaWaylandBuffer *buffer,
gboolean meta_wayland_egl_stream_attach (MetaWaylandEglStream *stream,
GError **error);
CoglTexture2D * meta_wayland_egl_stream_create_texture (MetaWaylandEglStream *stream,
GError **error);
CoglMultiPlaneTexture * meta_wayland_egl_stream_create_texture (MetaWaylandEglStream *stream,
GError **error);
CoglSnippet * meta_wayland_egl_stream_create_snippet (void);
gboolean meta_wayland_egl_stream_is_y_inverted (MetaWaylandEglStream *stream);

View File

@@ -266,7 +266,7 @@ meta_wayland_seat_free (MetaWaylandSeat *seat)
meta_wayland_gtk_text_input_destroy (seat->gtk_text_input);
meta_wayland_text_input_destroy (seat->text_input);
g_slice_free (MetaWaylandSeat, seat);
g_free (seat);
}
static gboolean

View File

@@ -153,7 +153,7 @@ meta_wayland_shell_surface_surface_commit (MetaWaylandSurfaceRole *surface_role
MetaWaylandSurfaceRoleClass *surface_role_class;
MetaWindow *window;
MetaWaylandBuffer *buffer;
CoglTexture *texture;
CoglMultiPlaneTexture *texture;
double scale;
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);
texture = meta_wayland_surface_get_texture (surface);
window->buffer_rect.width = cogl_texture_get_width (texture) * scale;
window->buffer_rect.height = cogl_texture_get_height (texture) * scale;
window->buffer_rect.width = cogl_multi_plane_texture_get_width (texture) * scale;
window->buffer_rect.height = cogl_multi_plane_texture_get_height (texture) * scale;
}
static void

View File

@@ -247,7 +247,7 @@ get_buffer_width (MetaWaylandSurface *surface)
MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
if (buffer)
return cogl_texture_get_width (surface->texture);
return cogl_multi_plane_texture_get_width (surface->texture);
else
return 0;
}
@@ -258,7 +258,7 @@ get_buffer_height (MetaWaylandSurface *surface)
MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
if (buffer)
return cogl_texture_get_height (surface->texture);
return cogl_multi_plane_texture_get_height (surface->texture);
else
return 0;
}
@@ -722,7 +722,7 @@ meta_wayland_surface_apply_pending_state (MetaWaylandSurface *surface,
if (changed_texture && meta_wayland_surface_get_actor (surface))
{
MetaShapedTexture *stex;
CoglTexture *texture;
CoglMultiPlaneTexture *texture;
CoglSnippet *snippet;
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);
}
CoglTexture *
CoglMultiPlaneTexture *
meta_wayland_surface_get_texture (MetaWaylandSurface *surface)
{
return surface->texture;

View File

@@ -149,7 +149,7 @@ struct _MetaWaylandSurface
GHashTable *outputs_to_destroy_notify_id;
MetaMonitorTransform buffer_transform;
CoglTexture *texture;
CoglMultiPlaneTexture *texture;
/* Buffer reference state. */
struct {
@@ -319,7 +319,7 @@ void meta_wayland_surface_restore_shortcuts (MetaWaylandSurface *
gboolean meta_wayland_surface_is_shortcuts_inhibited (MetaWaylandSurface *surface,
MetaWaylandSeat *seat);
CoglTexture * meta_wayland_surface_get_texture (MetaWaylandSurface *surface);
CoglMultiPlaneTexture * meta_wayland_surface_get_texture (MetaWaylandSurface *surface);
MetaSurfaceActor * meta_wayland_surface_get_actor (MetaWaylandSurface *surface);

View File

@@ -306,6 +306,26 @@ meta_wayland_log_func (const char *fmt,
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
meta_wayland_compositor_init (MetaWaylandCompositor *compositor)
{
@@ -318,6 +338,8 @@ meta_wayland_compositor_init (MetaWaylandCompositor *compositor)
compositor->wayland_display = wl_display_create ();
if (compositor->wayland_display == NULL)
g_error ("Failed to create the global wl_display");
add_supported_shm_formats (compositor->wayland_display);
}
static void