Compare commits

..

36 Commits

Author SHA1 Message Date
f1484fa6c2 Add dcvviewer to xwayland_grab_default_access_rules
dcvviewer does not have native wayland support yet

https://gitlab.gnome.org/GNOME/mutter/merge_requests/587
2019-05-22 14:55:03 +00:00
deef9960a4 Fix typo in RemoteDesktop dbus api
https://gitlab.gnome.org/GNOME/mutter/merge_requests/586
2019-05-22 16:21:57 +02:00
9305b6d8ee cogl/tests: Remove configure_file workaround for installed tests
Since starting meson 0.50 `install: false` is honored when the install_dir is
set to a non-empty value, we can now remove the workaround we added in commit
dbe73c329

https://gitlab.gnome.org/GNOME/mutter/merge_requests/585
2019-05-21 12:36:15 -05:00
62de4b4f82 meson: Bump meson requirement to 0.50.0
We've been using configure_file's `install` property for some time now, but this
has been officially supported and works as expected only since meson 0.50, so,
bump version to avoid warnings and ensure the behavior is the one we want.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/585
2019-05-21 12:36:13 -05:00
ea0a89bde8 cogl/meson: Remove uneeded cogl-mutter-config.h generation
This was needed until we had autotools in place.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/585
2019-05-21 12:36:10 -05:00
4faeb12731 clutter/stage-cogl: Reschedule update on present
If an update (new frame) had been scheduled already before
`_clutter_stage_cogl_presented` was called then that means it was
scheduled for the wrong time. Because the `last_presentation_time` has
changed since then. And using an `update_time` based on an outdated
presentation time results in scheduling frames too early, filling the
buffer queue (triple buffering or worse) and high visual latency.

So if we do receive a presentation event when an update is already
scheduled, remember to reschedule the update based on the newer
`last_presentation_time`. This way we avoid overfilling the buffer queue
and limit ourselves to double buffering for less visible lag.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/334

Prerequisite: https://gitlab.gnome.org/GNOME/mutter/merge_requests/520

https://gitlab.gnome.org/GNOME/mutter/merge_requests/281
2019-05-21 16:23:49 +00:00
91ac64bb44 drm-buffer: Make the "types" actual types
There is no reason why we should have an internal type enum when we have
all the infrastructure to just use multiple GObject types. Also there
was no code sharing between the old "types", the only common API was
getting the framebuffer ID, so lets make that a vfunc.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/584
2019-05-21 14:55:38 +00:00
ed56edc7ba drm-buffer: Remove useless soft-asserts
If triggered, many would result in crashes later anyway, so lets change
those to asserts. Some are simply useless, so remove those.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/584
2019-05-21 14:55:38 +00:00
6eeba2434a drm-buffer: Clean up file descriptor variable naming
Nowhere else is it called 'drm_fd' so lets not get rid of this
inconsistency.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/584
2019-05-21 14:55:38 +00:00
7fb7b28cd6 kms-buffer: Rename to MetaDrmBuffer
MetaKms* will be a dedicated namespace, which MetaKmsBuffer doesn't fit
under.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/584
2019-05-21 14:55:38 +00:00
08aec58c22 kms-buffer: Clean up include order
https://gitlab.gnome.org/GNOME/mutter/merge_requests/584
2019-05-21 14:55:38 +00:00
52945f383d launcher: Explicitly look up object path for seat
If mutter is running as a systemd user service, then we cannot use the
magic "self" session for the ID lookup. For now we need to lookup the ID
explicitly. Eventually we can change to use the magic "auto" paths for
both the session and seat, but that will require systemd v243.

See also https://github.com/systemd/systemd/pull/12424#issuecomment-487962314

https://gitlab.gnome.org/GNOME/mutter/merge_requests/571
2019-05-21 16:43:09 +02:00
fecc57ddf0 renderer-native: Reference count front buffers
Start reference counting front buffers instead of assuming we know
their (scanout) lifetimes.

Functionally, this should not change anything.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/119
2019-05-21 15:49:42 +02:00
0d7a929b83 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-05-21 15:20:44 +02:00
991f9505ad 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-05-21 15:20:44 +02:00
358b67871f boxes: Assign input to output rect when there's no transformation
https://gitlab.gnome.org/GNOME/mutter/merge_requests/469
2019-05-21 08:50:09 +00:00
2b1acea1b0 place: Assign anchor rect using automatic copy
Set the offsets in different statements.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/469
2019-05-21 08:50:09 +00:00
91aee3d5c4 monitor: Assign monitor layout directly by crtc rect
There's no need to repeat what gcc can do alone.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/469
2019-05-21 08:50:09 +00:00
02812fb988 clutter/stage-cogl: Damage fb using ceiled scaled sizes
https://gitlab.gnome.org/GNOME/mutter/merge_requests/469
2019-05-21 08:50:09 +00:00
29211c9020 clutter/util: Fix styling on functions definitions
https://gitlab.gnome.org/GNOME/mutter/merge_requests/469
2019-05-21 08:50:09 +00:00
68fba458b3 boxes: Ensure we scale to a fully rounded rectangle
In order to scale a rectangle by a double value, we can reuse a ClutterRect
to do the scale computations in floating point math and then to convert it back
using the proper strategy that will take in account the subpixel compensation.

In this way we can be sure that the resulting rectangle can fully contain the
original scaled one.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/469
2019-05-21 08:50:09 +00:00
9c2fdcdbb2 ci: Update Dockerfile to :v2
This commit is a bit deceitful: The main change in the image is *not* the
more recent Fedora base, but an updated (and not backward-compatible)
evolution-data-server package from the fmuellner/gnome-shell-ci copr.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/501 ports
gnome-shell to the new API, so to keep mutter and gnome-shell CI
working after that change, we need to build against the correct
EDS version.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/582
2019-05-20 19:44:57 +02:00
d4a0893d76 ci: Disable a11y bus for tests
While the regular session bus is provided by `dbus-run-session`, the
a11y bus is spawn by the "normal" D-Bus daemon (that is, dbus-broker
in F30). This currently fails, either due to a bug or some missing
dependencies in the container environment. But as we don't actually
need the additional bus, just disable it via the environment to make
not break tests when updating the base image to F30.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/582
2019-05-20 19:44:09 +02:00
7a6c755833 clutter: Add fribidi dependency and copy deprecated pango functions
Pango functions pango_unichar_direction() and pango_find_base_dir() have been
deprecated in pango 1.44, since these are used mostly clutter and gtk, copy the
code from pango and use fribidi dependency explicitly.

This is the same strategy used by Gtk.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/583
2019-05-17 18:11:43 -05:00
45244852ac clutter/stage-cogl: Don't skip over the next frame
The `last_presentation_time` is usually a little in the past (although
sometimes in the future depending on the driver). When it's over 2ms
(`sync_delay`) in the past that would trigger the while loop to count up so
that the next `update_time` is in the future.

The problem with that is for common values of `last_presentation_time`
which are only a few milliseconds ago, incrementing `update_time` by
`refresh_interval` also means counting past the next physical frame that
we haven't rendered yet. And so mutter would skip that frame.

**Example**

Given:
```
  last_presentation_time = now - 3ms
  sync_delay = 2ms
  refresh_interval = 16ms
  next_presentation_time = last_presentation_time + refresh_interval
                         = now + 13ms

          -3ms now        +13ms           +29ms           +45ms
        ----|--+------------|---------------|---------------|----
            :               :
  last_presentation_time  next_presentation_time
```

Old algorithm:
```
  update_time = last_presentation_time + sync_delay
              = now - 1ms
  while (update_time < now)
        (now - 1ms   < now)
    update_time = now - 1ms + 16ms
  update_time = now + 15ms
  next_presentation_time = now + 13ms
  available_render_time = next_presentation_time - max(now, update_time)
                        = (now + 13ms) - (now + 15ms)
                        = -2ms  so the next frame will be skipped.

          -3ms now        +13ms           +29ms           +45ms
        ----|--+------------|-+-------------|---------------|----
            :               : :
            :               : update_time (too late)
            :               :
  last_presentation_time  next_presentation_time (a missed frame)

```

New algorithm:
```
  min_render_time_allowed = refresh_interval / 2
                          = 8ms
  max_render_time_allowed = refresh_interval - sync_delay
                          = 14ms
  target_presentation_time = last_presentation_time + refresh_interval
                           = now - 3ms + 16ms
                           = now + 13ms
  while (target_presentation_time - min_render_time_allowed < now)
        (now + 13ms - 8ms < now)
        (5ms < 0ms)
    # loop is never entered
  update_time = target_presentation_time - max_render_time_allowed
              = now + 13ms - 14ms
              = now - 1ms
  next_presentation_time = now + 13ms
  available_render_time = next_presentation_time - max(now, update_time)
                        = (now + 13ms) - now
                        = 13ms  which is plenty of render time.

          -3ms now        +13ms           +29ms           +45ms
        ----|-++------------|---------------|---------------|----
            : :             :
            : update_time   :
            :               :
  last_presentation_time  next_presentation_time
```

The reason nobody noticed these missed frames very often was because
mutter has some accidental workarounds built-in:

 * Prior to 3.32, the offending code was only reachable in Xorg sessions.
   It was never reached in Wayland sessions because it hadn't been
   implemented yet (till e9e4b2b72).

 * Even though Wayland support is now implemented the native backend
   provides a `last_presentation_time` much faster than Xorg sessions
   (being in the same process) and so is less likely to spuriously enter
   the while loop to miss a frame.

 * For Xorg sessions we are accidentally triple buffering (#334). This
   is a good way to avoid the missed frames, but is also an accident.

 * `sync_delay` is presently just high enough (2ms by coincidence is very
   close to common values of `now - last_presentation_time`) to push the
   `update_time` into the future in some cases, which avoids entering the
   while loop. This is why the same missed frames problem was also noticed
   when experimenting with `sync_delay = 0`.

v2: adjust variable names and code style.

Fixes: https://bugzilla.gnome.org/show_bug.cgi?id=789186
       and most of https://gitlab.gnome.org/GNOME/mutter/issues/571

https://gitlab.gnome.org/GNOME/mutter/merge_requests/520
2019-05-16 22:13:54 +00:00
e96136e418 gitlab-ci: Use MALLOC_CHECK_ and MALLOC_PERTURB_ env variables in tests
Linux glibc supports a malloc implementation that is allows to be tunable using
environment variables, to check allocation issues.

When MALLOC_CHECK_ is set to 3, a diagnostic message is printed on stderr and
the program is aborted.

Setting the MALLOC_PERTURB_ environment variable causes the malloc functions in
to return memory which has been wiped and initialized with the byte value of the
environment variable.

So use this features when running tests in order to catch better memory errors.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/578
2019-05-16 21:30:36 +00:00
eae6e7a889 Updated Spanish translation 2019-05-16 12:42:33 +02:00
a48b6cc9ca clutter/actor: Fix a wrong comment
https://gitlab.gnome.org/GNOME/mutter/merge_requests/547
2019-05-15 20:38:28 +00:00
786305f7d6 clutter/input-device: Replace device check with assertion
We only call _clutter_input_device_update with devices that are not
Keyboard devices. Also passing a Keyboard device to a function whose
primary purpose is picking should be considered a bug in the caller.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/547
2019-05-15 20:38:28 +00:00
30a2483e6e clutter/stage-cogl: Fix a comment-typo
https://gitlab.gnome.org/GNOME/mutter/merge_requests/547
2019-05-15 20:38:28 +00:00
f5f0aa1023 clutter/stage: Move a comment to a more appropriate place
https://gitlab.gnome.org/GNOME/mutter/merge_requests/547
2019-05-15 20:38:28 +00:00
b86fba2f3c clutter/stage: Avoid unnecessary call to add_redraw_clip
We're bailing out of clutter_stage_cogl_add_redraw_clip() early without
doing anything if we're ignoring redraw clips, so no need to call it if
we already know that will be the case.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/547
2019-05-15 20:38:28 +00:00
f7ecf3b618 meta: Remove meta_free_gslist_and_elements
This function was added for historic reasons, before that we had GSlist's
free_full function.

Since this can be now easily implemented with a function call and an explicit
GDestroyFunc, while no known dependency uses it let's move to use
g_slist_free_func instead.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/57
2019-05-15 14:49:56 -05:00
7a17e236f7 Use free_full on GSList's instead of foreach + free
GList's used in legacy code were free'd using a g_slist_foreach + g_slist_free,
while we can just use g_slist_free_full as per GLib 2.28.

So replace code where we were using this legacy codepath.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/576
2019-05-15 14:49:56 -05:00
df7d8e2cbf Use free_full on GList's instead of foreach + free
GList's used in legacy code were free'd using a g_list_foreach + g_list_free,
while we can just use g_list_free_full as per GLib 2.28.

So replace code where we were using this legacy codepath.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/576
2019-05-15 14:42:25 -05:00
9e82f9af25 x11: Do not warn on cancelled X11 selection sources
This shouldn't happen frequently, but is just a sign that the source is
being replaced by something else. Just keep the warning for other possible
error situations.

Also, plug the potential GError leak.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/598
2019-05-15 13:14:12 +00:00
64 changed files with 1341 additions and 660 deletions

View File

@ -1,4 +1,4 @@
image: registry.gitlab.gnome.org/gnome/mutter/master:v1
image: registry.gitlab.gnome.org/gnome/mutter/master:v2
stages:
- review
@ -35,10 +35,13 @@ test-mutter:
variables:
XDG_RUNTIME_DIR: "$CI_PROJECT_DIR/runtime-dir"
GSETTINGS_SCHEMA_DIR: "$CI_PROJECT_DIR/build/data"
MALLOC_CHECK_: "3"
NO_AT_BRIDGE: "1"
script:
- mkdir -m 700 $XDG_RUNTIME_DIR
- glib-compile-schemas $GSETTINGS_SCHEMA_DIR
- >
env MALLOC_PERTURB_="$((RANDOM % 256 + 1))"
dbus-run-session -- xvfb-run -s '+iglx -noreset'
meson test -C build --no-rebuild -t 10 --verbose --no-stdsplit --wrap catchsegv
only:

View File

@ -1,4 +1,4 @@
FROM fedora:29
FROM fedora:30
RUN dnf -y update && dnf -y upgrade && \
dnf install -y 'dnf-command(builddep)' && \

View File

@ -1044,10 +1044,8 @@ _cally_actor_clean_action_list (CallyActor *cally_actor)
if (priv->action_list)
{
g_list_foreach (priv->action_list,
(GFunc) _cally_actor_destroy_action_info,
NULL);
g_list_free (priv->action_list);
g_list_free_full (priv->action_list,
(GDestroyNotify) _cally_actor_destroy_action_info);
priv->action_list = NULL;
}
}

View File

@ -577,8 +577,7 @@ _clutter_meta_group_clear_metas (ClutterMetaGroup *group)
{
g_list_foreach (group->meta, (GFunc) _clutter_actor_meta_set_actor, NULL);
g_list_foreach (group->meta, (GFunc) g_object_unref, NULL);
g_list_free (group->meta);
g_list_free_full (group->meta, g_object_unref);
group->meta = NULL;
}

View File

@ -8849,9 +8849,9 @@ _clutter_actor_queue_redraw_full (ClutterActor *self,
*
* later during _clutter_stage_do_update(), once relayouting is done
* and the scenegraph has been updated we will call:
* _clutter_stage_finish_queue_redraws().
* clutter_stage_maybe_finish_queue_redraws().
*
* _clutter_stage_finish_queue_redraws() will call
* clutter_stage_maybe_finish_queue_redraws() will call
* _clutter_actor_finish_queue_redraw() for each listed actor.
*
* Note: actors *are* allowed to queue further redraws during this

View File

@ -235,8 +235,7 @@ clutter_binding_pool_finalize (GObject *gobject)
g_hash_table_destroy (pool->entries_hash);
g_slist_foreach (pool->entries, (GFunc) binding_entry_free, NULL);
g_slist_free (pool->entries);
g_slist_free_full (pool->entries, (GDestroyNotify) binding_entry_free);
G_OBJECT_CLASS (clutter_binding_pool_parent_class)->finalize (gobject);
}

View File

@ -1036,9 +1036,10 @@ _clutter_input_device_update (ClutterInputDevice *device,
ClutterActor *new_cursor_actor;
ClutterActor *old_cursor_actor;
ClutterPoint point = { -1, -1 };
ClutterInputDeviceType device_type = device->device_type;
if (device->device_type == CLUTTER_KEYBOARD_DEVICE)
return NULL;
g_assert (device_type != CLUTTER_KEYBOARD_DEVICE &&
device_type != CLUTTER_PAD_DEVICE);
stage = device->stage;
if (G_UNLIKELY (stage == NULL))

View File

@ -412,8 +412,7 @@ master_clock_advance_timelines (ClutterMasterClockDefault *master_clock)
for (l = timelines; l != NULL; l = l->next)
_clutter_timeline_do_tick (l->data, master_clock->cur_tick / 1000);
g_slist_foreach (timelines, (GFunc) g_object_unref, NULL);
g_slist_free (timelines);
g_slist_free_full (timelines, g_object_unref);
#ifdef CLUTTER_ENABLE_DEBUG
if (_clutter_diagnostic_enabled ())
@ -574,8 +573,7 @@ clutter_clock_dispatch (GSource *source,
master_clock_reschedule_stage_updates (master_clock, stages);
g_slist_foreach (stages, (GFunc) g_object_unref, NULL);
g_slist_free (stages);
g_slist_free_full (stages, g_object_unref);
master_clock->prev_tick = master_clock->cur_tick;

View File

@ -295,8 +295,7 @@ clutter_path_clear (ClutterPath *path)
{
ClutterPathPrivate *priv = path->priv;
g_slist_foreach (priv->nodes, (GFunc) clutter_path_node_full_free, NULL);
g_slist_free (priv->nodes);
g_slist_free_full (priv->nodes, (GDestroyNotify) clutter_path_node_full_free);
priv->nodes = priv->nodes_tail = NULL;
priv->nodes_dirty = TRUE;
@ -659,8 +658,7 @@ clutter_path_parse_description (const gchar *p,
return TRUE;
fail:
g_slist_foreach (nodes, (GFunc) clutter_path_node_full_free, NULL);
g_slist_free (nodes);
g_slist_free_full (nodes, (GDestroyNotify) clutter_path_node_full_free);
return FALSE;
}

View File

@ -303,6 +303,11 @@ gboolean _clutter_util_matrix_decompose (const ClutterMatrix *src,
ClutterVertex *translate_p,
ClutterVertex4 *perspective_p);
PangoDirection _clutter_pango_unichar_direction (gunichar ch);
PangoDirection _clutter_pango_find_base_dir (const gchar *text,
gint length);
typedef struct _ClutterPlane
{
float v0[3];

View File

@ -2021,8 +2021,7 @@ add_children (ClutterScript *script,
clutter_container_add_actor (container, CLUTTER_ACTOR (object));
}
g_list_foreach (oinfo->children, (GFunc) g_free, NULL);
g_list_free (oinfo->children);
g_list_free_full (oinfo->children, g_free);
oinfo->children = unresolved;
}

View File

@ -346,15 +346,12 @@ object_info_free (gpointer data)
g_free (oinfo->class_name);
g_free (oinfo->type_func);
g_list_foreach (oinfo->properties, (GFunc) property_info_free, NULL);
g_list_free (oinfo->properties);
g_list_free_full (oinfo->properties, property_info_free);
g_list_foreach (oinfo->signals, (GFunc) signal_info_free, NULL);
g_list_free (oinfo->signals);
g_list_free_full (oinfo->signals, signal_info_free);
/* these are ids */
g_list_foreach (oinfo->children, (GFunc) g_free, NULL);
g_list_free (oinfo->children);
g_list_free_full (oinfo->children, g_free);
/* we unref top-level objects and leave the actors alone,
* unless we are unmerging in which case we have to destroy
@ -846,8 +843,7 @@ clutter_script_unmerge_objects (ClutterScript *script,
for (l = data.ids; l != NULL; l = l->next)
g_hash_table_remove (priv->objects, l->data);
g_slist_foreach (data.ids, (GFunc) g_free, NULL);
g_slist_free (data.ids);
g_slist_free_full (data.ids, g_free);
clutter_script_ensure_objects (script);
}

View File

@ -89,8 +89,8 @@ clutter_stage_manager_dispose (GObject *gobject)
stage_manager = CLUTTER_STAGE_MANAGER (gobject);
g_slist_foreach (stage_manager->stages, (GFunc) clutter_actor_destroy, NULL);
g_slist_free (stage_manager->stages);
g_slist_free_full (stage_manager->stages,
(GDestroyNotify) clutter_actor_destroy);
stage_manager->stages = NULL;
G_OBJECT_CLASS (clutter_stage_manager_parent_class)->dispose (gobject);

View File

@ -1303,14 +1303,8 @@ clutter_stage_real_queue_redraw (ClutterActor *actor,
return TRUE;
if (_clutter_stage_window_ignoring_redraw_clips (stage_window))
{
_clutter_stage_window_add_redraw_clip (stage_window, NULL);
return FALSE;
}
return FALSE;
/* Convert the clip volume into stage coordinates and then into an
* axis aligned stage coordinates bounding box...
*/
if (redraw_clip == NULL)
{
_clutter_stage_window_add_redraw_clip (stage_window, NULL);
@ -1320,6 +1314,8 @@ clutter_stage_real_queue_redraw (ClutterActor *actor,
if (redraw_clip->is_empty)
return TRUE;
/* Convert the clip volume into stage coordinates and then into an
* axis aligned stage coordinates bounding box... */
_clutter_paint_volume_get_stage_paint_box (redraw_clip,
stage,
&bounding_box);

View File

@ -751,7 +751,7 @@ clutter_text_create_layout_no_cache (ClutterText *text,
if (priv->password_char != 0)
pango_dir = PANGO_DIRECTION_NEUTRAL;
else
pango_dir = pango_find_base_dir (contents, contents_len);
pango_dir = _clutter_pango_find_base_dir (contents, contents_len);
if (pango_dir == PANGO_DIRECTION_NEUTRAL)
{

View File

@ -32,6 +32,7 @@
#include "clutter-build-config.h"
#include <fribidi.h>
#include <math.h>
#include "clutter-debug.h"
@ -105,8 +106,9 @@ _clutter_util_fully_transform_vertices (const CoglMatrix *modelview,
}
}
void _clutter_util_rect_from_rectangle (const cairo_rectangle_int_t *src,
ClutterRect *dest)
void
_clutter_util_rect_from_rectangle (const cairo_rectangle_int_t *src,
ClutterRect *dest)
{
*dest = (ClutterRect) {
.origin = {
@ -120,8 +122,9 @@ void _clutter_util_rect_from_rectangle (const cairo_rectangle_int_t *src,
};
}
void _clutter_util_rectangle_int_extents (const ClutterRect *src,
cairo_rectangle_int_t *dest)
void
_clutter_util_rectangle_int_extents (const ClutterRect *src,
cairo_rectangle_int_t *dest)
{
ClutterRect tmp = *src;
@ -135,10 +138,11 @@ void _clutter_util_rectangle_int_extents (const ClutterRect *src,
};
}
void _clutter_util_rectangle_offset (const cairo_rectangle_int_t *src,
int x,
int y,
cairo_rectangle_int_t *dest)
void
_clutter_util_rectangle_offset (const cairo_rectangle_int_t *src,
int x,
int y,
cairo_rectangle_int_t *dest)
{
*dest = *src;
@ -696,3 +700,45 @@ clutter_interval_register_progress_func (GType value_type,
G_UNLOCK (progress_funcs);
}
PangoDirection
_clutter_pango_unichar_direction (gunichar ch)
{
FriBidiCharType fribidi_ch_type;
G_STATIC_ASSERT (sizeof (FriBidiChar) == sizeof (gunichar));
fribidi_ch_type = fribidi_get_bidi_type (ch);
if (!FRIBIDI_IS_STRONG (fribidi_ch_type))
return PANGO_DIRECTION_NEUTRAL;
else if (FRIBIDI_IS_RTL (fribidi_ch_type))
return PANGO_DIRECTION_RTL;
else
return PANGO_DIRECTION_LTR;
}
PangoDirection
_clutter_pango_find_base_dir (const gchar *text,
gint length)
{
PangoDirection dir = PANGO_DIRECTION_NEUTRAL;
const gchar *p;
g_return_val_if_fail (text != NULL || length == 0, PANGO_DIRECTION_NEUTRAL);
p = text;
while ((length < 0 || p < text + length) && *p)
{
gunichar wc = g_utf8_get_char (p);
dir = _clutter_pango_unichar_direction (wc);
if (dir != PANGO_DIRECTION_NEUTRAL)
break;
p = g_utf8_next_char (p);
}
return dir;
}

View File

@ -77,6 +77,10 @@ enum
PROP_LAST
};
static void
clutter_stage_cogl_schedule_update (ClutterStageWindow *stage_window,
gint sync_delay);
static void
clutter_stage_cogl_unrealize (ClutterStageWindow *stage_window)
{
@ -122,6 +126,16 @@ _clutter_stage_cogl_presented (ClutterStageCogl *stage_cogl,
}
_clutter_stage_presented (stage_cogl->wrapper, frame_event, frame_info);
if (frame_event == COGL_FRAME_EVENT_COMPLETE &&
stage_cogl->update_time != -1)
{
ClutterStageWindow *stage_window = CLUTTER_STAGE_WINDOW (stage_cogl);
stage_cogl->update_time = -1;
clutter_stage_cogl_schedule_update (stage_window,
stage_cogl->last_sync_delay);
}
}
static gboolean
@ -152,10 +166,15 @@ clutter_stage_cogl_schedule_update (ClutterStageWindow *stage_window,
gint64 now;
float refresh_rate;
gint64 refresh_interval;
int64_t min_render_time_allowed;
int64_t max_render_time_allowed;
int64_t next_presentation_time;
if (stage_cogl->update_time != -1)
return;
stage_cogl->last_sync_delay = sync_delay;
now = g_get_monotonic_time ();
if (sync_delay < 0)
@ -184,10 +203,18 @@ clutter_stage_cogl_schedule_update (ClutterStageWindow *stage_window,
if (refresh_interval == 0)
refresh_interval = 16667; /* 1/60th second */
stage_cogl->update_time = stage_cogl->last_presentation_time + 1000 * sync_delay;
min_render_time_allowed = refresh_interval / 2;
max_render_time_allowed = refresh_interval - 1000 * sync_delay;
while (stage_cogl->update_time < now)
stage_cogl->update_time += refresh_interval;
if (min_render_time_allowed > max_render_time_allowed)
min_render_time_allowed = max_render_time_allowed;
next_presentation_time = stage_cogl->last_presentation_time + refresh_interval;
while (next_presentation_time < now + min_render_time_allowed)
next_presentation_time += refresh_interval;
stage_cogl->update_time = next_presentation_time - max_render_time_allowed;
}
static gint64
@ -273,7 +300,7 @@ clutter_stage_cogl_ignoring_redraw_clips (ClutterStageWindow *stage_window)
}
/* A redraw clip represents (in stage coordinates) the bounding box of
* something that needs to be redraw. Typically they are added to the
* something that needs to be redrawn. Typically they are added to the
* StageWindow as a result of clutter_actor_queue_clipped_redraw() by
* actors such as ClutterGLXTexturePixmap. All redraw clips are
* discarded after the next paint.
@ -502,8 +529,8 @@ fill_current_damage_history_and_step (ClutterStageView *view)
*current_fb_damage = (cairo_rectangle_int_t) {
.x = 0,
.y = 0,
.width = view_rect.width * fb_scale,
.height = view_rect.height * fb_scale
.width = ceilf (view_rect.width * fb_scale),
.height = ceilf (view_rect.height * fb_scale)
};
view_priv->damage_index++;
}

View File

@ -59,6 +59,8 @@ struct _ClutterStageCogl
* junk frames to start with. */
unsigned int frame_count;
gint last_sync_delay;
cairo_rectangle_int_t bounding_redraw_clip;
guint initialized_redraw_clip : 1;

View File

@ -250,7 +250,8 @@ get_direction (XkbDescPtr xkb,
{
int level = 0;
KeySym sym = XkbKeySymEntry (xkb, code, level, group);
PangoDirection dir = pango_unichar_direction (clutter_keysym_to_unicode (sym));
PangoDirection dir =
_clutter_pango_unichar_direction (clutter_keysym_to_unicode (sym));
switch (dir)
{

View File

@ -38,6 +38,7 @@ clutter_pkg_deps = [
]
clutter_pkg_private_deps = [
fribidi_dep,
gdk_pixbuf_dep,
gthread_dep,
gmodule_no_export_dep,

View File

@ -114,8 +114,7 @@ test_destroy_destroy (ClutterActor *self)
test->tex = NULL;
}
g_list_foreach (test->children, (GFunc) clutter_actor_destroy, NULL);
g_list_free (test->children);
g_list_free_full (test->children, (GDestroyNotify) clutter_actor_destroy);
test->children = NULL;
if (CLUTTER_ACTOR_CLASS (test_destroy_parent_class)->destroy)

View File

@ -38,8 +38,7 @@ timeline_data_init (TimelineData *data, int timeline_num)
static void
timeline_data_destroy (TimelineData *data)
{
g_slist_foreach (data->markers_hit, (GFunc) g_free, NULL);
g_slist_free (data->markers_hit);
g_slist_free_full (data->markers_hit, g_free);
}
static void

View File

@ -483,8 +483,8 @@ _cogl_pango_display_list_node_free (CoglPangoDisplayListNode *node)
void
_cogl_pango_display_list_clear (CoglPangoDisplayList *dl)
{
g_slist_foreach (dl->nodes, (GFunc) _cogl_pango_display_list_node_free, NULL);
g_slist_free (dl->nodes);
g_slist_free_full (dl->nodes, (GDestroyNotify)
_cogl_pango_display_list_node_free);
dl->nodes = NULL;
dl->last_node = NULL;
}

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

@ -31,7 +31,7 @@
#ifndef __COGL_MUTTER_H___
#define __COGL_MUTTER_H___
#include "cogl-mutter-config.h"
#include "cogl-config.h"
#include "cogl-defines.h"
#include <cogl/cogl-texture.h>

View File

@ -456,11 +456,7 @@ _cogl_pipeline_free (CoglPipeline *pipeline)
g_slice_free (CoglPipelineBigState, pipeline->big_state);
if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS)
{
g_list_foreach (pipeline->layer_differences,
(GFunc)cogl_object_unref, NULL);
g_list_free (pipeline->layer_differences);
}
g_list_free_full (pipeline->layer_differences, cogl_object_unref);
if (pipeline->differences & COGL_PIPELINE_STATE_VERTEX_SNIPPETS)
_cogl_pipeline_snippet_list_free (&pipeline->big_state->vertex_snippets);
@ -937,12 +933,7 @@ _cogl_pipeline_copy_differences (CoglPipeline *dest,
if (dest->differences & COGL_PIPELINE_STATE_LAYERS &&
dest->layer_differences)
{
g_list_foreach (dest->layer_differences,
(GFunc)cogl_object_unref,
NULL);
g_list_free (dest->layer_differences);
}
g_list_free_full (dest->layer_differences, cogl_object_unref);
for (l = src->layer_differences; l; l = l->next)
{

View File

@ -0,0 +1,310 @@
/*
* 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) */
} CoglPixelFormatInfo;
static const CoglPixelFormatInfo format_info_table[] = {
{
.cogl_format = COGL_PIXEL_FORMAT_ANY,
.format_str = "ANY",
.bpp = 0,
.aligned = -1
},
{
.cogl_format = COGL_PIXEL_FORMAT_A_8,
.format_str = "A_8",
.bpp = 1,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGB_565,
.format_str = "RGB_565",
.bpp = 2,
.aligned = 0
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_4444,
.format_str = "RGBA_4444",
.bpp = 2,
.aligned = 0
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_5551,
.format_str = "RGBA_5551",
.bpp = 2,
.aligned = 0
},
{
.cogl_format = COGL_PIXEL_FORMAT_YUV,
.format_str = "YUV",
.bpp = 0,
.aligned = -1
},
{
.cogl_format = COGL_PIXEL_FORMAT_G_8,
.format_str = "G_8",
.bpp = 1,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RG_88,
.format_str = "RG_88",
.bpp = 2,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGB_888,
.format_str = "RGB_888",
.bpp = 3,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_BGR_888,
.format_str = "BGR_888",
.bpp = 3,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_8888,
.format_str = "RGBA_8888",
.bpp = 4,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_BGRA_8888,
.format_str = "BGRA_8888",
.bpp = 4,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_ARGB_8888,
.format_str = "ARGB_8888",
.bpp = 4,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_ABGR_8888,
.format_str = "ABGR_8888",
.bpp = 4,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_1010102,
.format_str = "RGBA_1010102",
.bpp = 4,
.aligned = 0
},
{
.cogl_format = COGL_PIXEL_FORMAT_BGRA_1010102,
.format_str = "BGRA_1010102",
.bpp = 4,
.aligned = 0
},
{
.cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010,
.format_str = "ARGB_2101010",
.bpp = 4,
.aligned = 0
},
{
.cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010,
.format_str = "ABGR_2101010",
.bpp = 4,
.aligned = 0
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE,
.format_str = "RGBA_8888_PRE",
.bpp = 4,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_BGRA_8888_PRE,
.format_str = "BGRA_8888_PRE",
.bpp = 4,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE,
.format_str = "ARGB_8888_PRE",
.bpp = 4,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_ABGR_8888_PRE,
.format_str = "ABGR_8888_PRE",
.bpp = 4,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_4444_PRE,
.format_str = "RGBA_4444_PRE",
.bpp = 2,
.aligned = 0
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_5551_PRE,
.format_str = "RGBA_5551_PRE",
.bpp = 2,
.aligned = 0
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_1010102_PRE,
.format_str = "RGBA_1010102_PRE",
.bpp = 4,
.aligned = 0
},
{
.cogl_format = COGL_PIXEL_FORMAT_BGRA_1010102_PRE,
.format_str = "BGRA_1010102_PRE",
.bpp = 4,
.aligned = 0
},
{
.cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010_PRE,
.format_str = "ARGB_2101010_PRE",
.bpp = 4,
.aligned = 0
},
{
.cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010_PRE,
.format_str = "ABGR_2101010_PRE",
.bpp = 4,
.aligned = 0
},
{
.cogl_format = COGL_PIXEL_FORMAT_DEPTH_16,
.format_str = "DEPTH_16",
.bpp = 2,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_DEPTH_32,
.format_str = "DEPTH_32",
.bpp = 4,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8,
.format_str = "DEPTH_24_STENCIL_8",
.bpp = 4,
.aligned = 1
},
};
/*
* 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 ();
}
/* 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;
}
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,300 @@
/*
* 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: 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;
/*
* _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_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

@ -194,10 +194,8 @@ _cogl_renderer_free (CoglRenderer *renderer)
if (renderer->libgl_module)
g_module_close (renderer->libgl_module);
g_slist_foreach (renderer->event_filters,
(GFunc) native_filter_closure_free,
NULL);
g_slist_free (renderer->event_filters);
g_slist_free_full (renderer->event_filters,
(GDestroyNotify) native_filter_closure_free);
g_array_free (renderer->poll_fds, TRUE);

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_YUV: ycbcr conversion 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

@ -64,6 +64,7 @@
#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>

View File

@ -59,10 +59,8 @@ _cogl_program_free (CoglProgram *program)
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* Unref all of the attached shaders */
g_slist_foreach (program->attached_shaders, (GFunc) cogl_handle_unref, NULL);
/* Destroy the list */
g_slist_free (program->attached_shaders);
/* Unref all of the attached shaders and destroy the list */
g_slist_free_full (program->attached_shaders, cogl_handle_unref);
for (i = 0; i < program->custom_uniforms->len; i++)
{

View File

@ -88,6 +88,7 @@ cogl_headers = [
'cogl-pipeline.h',
'cogl-pipeline-state.h',
'cogl-pipeline-layer-state.h',
'cogl-pixel-format.h',
'cogl-primitives.h',
'cogl-texture.h',
'cogl-texture-2d.h',
@ -233,6 +234,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',

View File

@ -14,12 +14,6 @@ cogl_config_h = configure_file(
output: 'cogl-config.h',
configuration: cdata)
# TODO: Remove this when autotools support is removed
cogl_mutter_config_h = configure_file(
input: 'cogl-config.h.meson',
output: 'cogl-mutter-config.h',
configuration: cdata)
cogl_pkg_deps = [
glib_dep,
gobject_dep,

View File

@ -4,19 +4,9 @@ cdata = configuration_data()
cdata.set('HAVE_GL', have_gl.to_int())
cdata.set('HAVE_GLES2', have_gles2.to_int())
# Until meson 0.50 setting the install parameter in 'configure_file' is ignored
# if 'install_dir' is set, then until mutter doesn't depend on such meson version
# cogl_installed_tests_libexecdir should be empty unless have_installed_tests
# is false, or this file will be installed anyway.
#
# See https://github.com/mesonbuild/meson/issues/4160
cogl_installed_tests_libexecdir = ''
if have_installed_tests
cogl_installed_tests_libexecdir = join_paths(
mutter_installed_tests_libexecdir, 'cogl', 'conform')
install_data('run-tests.sh', install_dir: cogl_installed_tests_libexecdir)
endif
cogl_installed_tests_libexecdir = join_paths(
mutter_installed_tests_libexecdir, 'cogl', 'conform')
install_data('run-tests.sh', install_dir: cogl_installed_tests_libexecdir)
cogl_config_env = configure_file(
input: 'config.env.in',

View File

@ -1,6 +1,6 @@
project('mutter', 'c',
version: '3.33.1',
meson_version: '>= 0.48.0',
meson_version: '>= 0.50.0',
license: 'GPLv2+'
)
@ -9,6 +9,7 @@ mutter_plugin_api_version = '3'
libmutter_api_version = '4'
# generic version requirements
fribidi_req = '>= 1.0.0'
glib_req = '>= 2.53.2'
gi_req = '>= 0.9.5'
gtk3_req = '>= 3.19.8'
@ -86,6 +87,7 @@ pango_dep = dependency('pango', version: pango_req)
cairo_dep = dependency('cairo', version: cairo_req)
cairo_gobject_dep = dependency('cairo-gobject', version: cairo_req)
pangocairo_dep = dependency('pangocairo', version: pangocairo_req)
fribidi_dep = dependency('fribidi', version: fribidi_req)
gsettings_desktop_schemas_dep = dependency('gsettings-desktop-schemas',
version: gsettings_desktop_schemas_req)
glib_dep = dependency('glib-2.0', version: glib_req)

View File

@ -143,6 +143,6 @@ option('xwayland_path',
option('xwayland_grab_default_access_rules',
type: 'string',
value: 'gnome-boxes,remote-viewer,virt-viewer,virt-manager,vinagre,vncviewer,Xephyr',
description: 'Comma delimited list of applications ressources or class allowed to issue X11 grabs in Xwayland'
value: 'gnome-boxes,remote-viewer,virt-viewer,virt-manager,vinagre,vncviewer,Xephyr,dcvviewer',
description: 'Comma delimited list of applications resources or class allowed to issue X11 grabs in Xwayland'
)

View File

@ -13,8 +13,8 @@ msgid ""
msgstr ""
"Project-Id-Version: mutter.master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n"
"POT-Creation-Date: 2019-05-03 10:54+0000\n"
"PO-Revision-Date: 2019-05-03 14:28+0200\n"
"POT-Creation-Date: 2019-05-15 13:19+0000\n"
"PO-Revision-Date: 2019-05-16 12:38+0200\n"
"Last-Translator: Daniel Mustieles <daniel.mustieles@gmail.com>\n"
"Language-Team: es <gnome-es-list@gnome.org>\n"
"Language: es\n"
@ -397,6 +397,16 @@ msgid "Enable experimental features"
msgstr "Activar las características experimentales"
#: data/org.gnome.mutter.gschema.xml.in:108
#| msgid ""
#| "To enable experimental features, add the feature keyword to the list. "
#| "Whether the feature requires restarting the compositor depends on the "
#| "given feature. Any experimental feature is not required to still be "
#| "available, or configurable. Dont expect adding anything in this setting "
#| "to be future proof. Currently possible keywords: • “scale-monitor-"
#| "framebuffer” — makes mutter default to layout logical monitors in a "
#| "logical pixel coordinate space, while scaling monitor framebuffers "
#| "instead of window content, to manage HiDPI monitors. Does not require a "
#| "restart."
msgid ""
"To enable experimental features, add the feature keyword to the list. "
"Whether the feature requires restarting the compositor depends on the given "
@ -405,7 +415,9 @@ msgid ""
"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes "
"mutter default to layout logical monitors in a logical pixel coordinate "
"space, while scaling monitor framebuffers instead of window content, to "
"manage HiDPI monitors. Does not require a restart."
"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes "
"mutter request a low priority real-time scheduling. The executable or user "
"must have CAP_SYS_NICE. Requires a restart."
msgstr ""
"Para activar las características experimentales, añada la palabra clave de "
"la característica a la lista. Depende de la característica que se deba "
@ -416,21 +428,23 @@ msgstr ""
"manera predeterminada de disponer monitores lógicos en un espacio lógico de "
"coordenadas de píxeles, al escalar framebuffers de monitores framebuffers en "
"lugar del contenido de ventana, para administrar monitores HiDPI. No "
"requiere un reinicio."
"requiere un reinicio. • “rt-scheduler” — hace que mutter pida una "
"planificación en tiempo real con prioridad baja. El ejecutable o el usuario "
"deben tener CAP_SYS_NICE. Requiere reniciar."
#: data/org.gnome.mutter.gschema.xml.in:141
#: data/org.gnome.mutter.gschema.xml.in:145
msgid "Select window from tab popup"
msgstr "Seleccionar ventana de la pestaña emergente"
#: data/org.gnome.mutter.gschema.xml.in:146
#: data/org.gnome.mutter.gschema.xml.in:150
msgid "Cancel tab popup"
msgstr "Cancelar pestaña emergente"
#: data/org.gnome.mutter.gschema.xml.in:151
#: data/org.gnome.mutter.gschema.xml.in:155
msgid "Switch monitor configurations"
msgstr "Cambiar la configuración del monitor"
#: data/org.gnome.mutter.gschema.xml.in:156
#: data/org.gnome.mutter.gschema.xml.in:160
msgid "Rotates the built-in monitor configuration"
msgstr "Rota la configuración del monitor empotrado"

View File

@ -589,12 +589,7 @@ meta_monitor_normal_derive_layout (MetaMonitor *monitor,
output = meta_monitor_get_main_output (monitor);
crtc = meta_output_get_assigned_crtc (output);
*layout = (MetaRectangle) {
.x = crtc->rect.x,
.y = crtc->rect.y,
.width = crtc->rect.width,
.height = crtc->rect.height
};
*layout = crtc->rect;
}
static gboolean

View File

@ -0,0 +1,65 @@
/*
* Copyright (C) 2011 Intel Corporation.
* Copyright (C) 2016 Red Hat
* Copyright (C) 2018 DisplayLink (UK) Ltd.
* Copyright (C) 2018 Canonical Ltd.
*
* 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.
*
*/
#include "config.h"
#include "backends/native/meta-drm-buffer-dumb.h"
struct _MetaDrmBufferDumb
{
MetaDrmBuffer parent;
uint32_t fb_id;
};
G_DEFINE_TYPE (MetaDrmBufferDumb, meta_drm_buffer_dumb, META_TYPE_DRM_BUFFER)
MetaDrmBufferDumb *
meta_drm_buffer_dumb_new (uint32_t dumb_fb_id)
{
MetaDrmBufferDumb *buffer_dumb;
buffer_dumb = g_object_new (META_TYPE_DRM_BUFFER_DUMB, NULL);
buffer_dumb->fb_id = dumb_fb_id;
return buffer_dumb;
}
static uint32_t
meta_drm_buffer_dumb_get_fb_id (MetaDrmBuffer *buffer)
{
return META_DRM_BUFFER_DUMB (buffer)->fb_id;
}
static void
meta_drm_buffer_dumb_init (MetaDrmBufferDumb *buffer_dumb)
{
}
static void
meta_drm_buffer_dumb_class_init (MetaDrmBufferDumbClass *klass)
{
MetaDrmBufferClass *buffer_class = META_DRM_BUFFER_CLASS (klass);
buffer_class->get_fb_id = meta_drm_buffer_dumb_get_fb_id;
}

View File

@ -0,0 +1,35 @@
/*
* Copyright (C) 2018 Canonical Ltd.
* Copyright (C) 2019 Red Hat Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
*/
#ifndef META_DRM_BUFFER_DUMB_H
#define META_DRM_BUFFER_DUMB_H
#include "backends/native/meta-drm-buffer.h"
#define META_TYPE_DRM_BUFFER_DUMB (meta_drm_buffer_dumb_get_type ())
G_DECLARE_FINAL_TYPE (MetaDrmBufferDumb,
meta_drm_buffer_dumb,
META, DRM_BUFFER_DUMB,
MetaDrmBuffer)
MetaDrmBufferDumb * meta_drm_buffer_dumb_new (uint32_t dumb_fb_id);
#endif /* META_DRM_BUFFER_DUMB_H */

View File

@ -0,0 +1,232 @@
/*
* Copyright (C) 2011 Intel Corporation.
* Copyright (C) 2016 Red Hat
* Copyright (C) 2018 DisplayLink (UK) Ltd.
* Copyright (C) 2018 Canonical Ltd.
*
* 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.
*
*/
#include "config.h"
#include "backends/native/meta-drm-buffer-gbm.h"
#include <drm_fourcc.h>
#include <errno.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
#define INVALID_FB_ID 0U
struct _MetaDrmBufferGbm
{
MetaDrmBuffer parent;
MetaGpuKms *gpu_kms;
struct gbm_surface *surface;
struct gbm_bo *bo;
uint32_t fb_id;
};
G_DEFINE_TYPE (MetaDrmBufferGbm, meta_drm_buffer_gbm, META_TYPE_DRM_BUFFER)
struct gbm_bo *
meta_drm_buffer_gbm_get_bo (MetaDrmBufferGbm *buffer_gbm)
{
return buffer_gbm->bo;
}
static gboolean
acquire_swapped_buffer (MetaDrmBufferGbm *buffer_gbm,
gboolean use_modifiers,
GError **error)
{
uint32_t handles[4] = {0, 0, 0, 0};
uint32_t strides[4] = {0, 0, 0, 0};
uint32_t offsets[4] = {0, 0, 0, 0};
uint64_t modifiers[4] = {0, 0, 0, 0};
uint32_t width, height;
uint32_t format;
struct gbm_bo *bo;
int kms_fd;
kms_fd = meta_gpu_kms_get_fd (buffer_gbm->gpu_kms);
bo = gbm_surface_lock_front_buffer (buffer_gbm->surface);
if (!bo)
{
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
"gbm_surface_lock_front_buffer failed");
return FALSE;
}
if (gbm_bo_get_handle_for_plane (bo, 0).s32 == -1)
{
/* Failed to fetch handle to plane, falling back to old method */
strides[0] = gbm_bo_get_stride (bo);
handles[0] = gbm_bo_get_handle (bo).u32;
offsets[0] = 0;
modifiers[0] = DRM_FORMAT_MOD_INVALID;
}
else
{
int i;
for (i = 0; i < gbm_bo_get_plane_count (bo); i++)
{
strides[i] = gbm_bo_get_stride_for_plane (bo, i);
handles[i] = gbm_bo_get_handle_for_plane (bo, i).u32;
offsets[i] = gbm_bo_get_offset (bo, i);
modifiers[i] = gbm_bo_get_modifier (bo);
}
}
width = gbm_bo_get_width (bo);
height = gbm_bo_get_height (bo);
format = gbm_bo_get_format (bo);
if (use_modifiers && modifiers[0] != DRM_FORMAT_MOD_INVALID)
{
if (drmModeAddFB2WithModifiers (kms_fd,
width, height,
format,
handles,
strides,
offsets,
modifiers,
&buffer_gbm->fb_id,
DRM_MODE_FB_MODIFIERS))
{
g_set_error (error,
G_IO_ERROR,
g_io_error_from_errno (errno),
"drmModeAddFB2WithModifiers failed: %s",
g_strerror (errno));
gbm_surface_release_buffer (buffer_gbm->surface, bo);
return FALSE;
}
}
else if (drmModeAddFB2 (kms_fd,
width,
height,
format,
handles,
strides,
offsets,
&buffer_gbm->fb_id,
0))
{
if (format != DRM_FORMAT_XRGB8888)
{
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
"drmModeAddFB does not support format 0x%x",
format);
gbm_surface_release_buffer (buffer_gbm->surface, bo);
return FALSE;
}
if (drmModeAddFB (kms_fd,
width,
height,
24,
32,
strides[0],
handles[0],
&buffer_gbm->fb_id))
{
g_set_error (error,
G_IO_ERROR,
g_io_error_from_errno (errno),
"drmModeAddFB failed: %s",
g_strerror (errno));
gbm_surface_release_buffer (buffer_gbm->surface, bo);
return FALSE;
}
}
buffer_gbm->bo = bo;
return TRUE;
}
MetaDrmBufferGbm *
meta_drm_buffer_gbm_new (MetaGpuKms *gpu_kms,
struct gbm_surface *gbm_surface,
gboolean use_modifiers,
GError **error)
{
MetaDrmBufferGbm *buffer_gbm;
buffer_gbm = g_object_new (META_TYPE_DRM_BUFFER_GBM, NULL);
buffer_gbm->gpu_kms = gpu_kms;
buffer_gbm->surface = gbm_surface;
if (!acquire_swapped_buffer (buffer_gbm, use_modifiers, error))
{
g_object_unref (buffer_gbm);
return NULL;
}
return buffer_gbm;
}
static uint32_t
meta_drm_buffer_gbm_get_fb_id (MetaDrmBuffer *buffer)
{
return META_DRM_BUFFER_GBM (buffer)->fb_id;
}
static void
meta_drm_buffer_gbm_finalize (GObject *object)
{
MetaDrmBufferGbm *buffer_gbm = META_DRM_BUFFER_GBM (object);
if (buffer_gbm->fb_id != INVALID_FB_ID)
{
int kms_fd;
kms_fd = meta_gpu_kms_get_fd (buffer_gbm->gpu_kms);
drmModeRmFB (kms_fd, buffer_gbm->fb_id);
}
if (buffer_gbm->bo)
gbm_surface_release_buffer (buffer_gbm->surface, buffer_gbm->bo);
G_OBJECT_CLASS (meta_drm_buffer_gbm_parent_class)->finalize (object);
}
static void
meta_drm_buffer_gbm_init (MetaDrmBufferGbm *buffer_gbm)
{
}
static void
meta_drm_buffer_gbm_class_init (MetaDrmBufferGbmClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
MetaDrmBufferClass *buffer_class = META_DRM_BUFFER_CLASS (klass);
object_class->finalize = meta_drm_buffer_gbm_finalize;
buffer_class->get_fb_id = meta_drm_buffer_gbm_get_fb_id;
}

View File

@ -0,0 +1,43 @@
/*
* Copyright (C) 2018 Canonical Ltd.
* Copyright (C) 2019 Red Hat Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
*/
#ifndef META_DRM_BUFFER_GBM_H
#define META_DRM_BUFFER_GBM_H
#include <gbm.h>
#include "backends/native/meta-drm-buffer.h"
#include "backends/native/meta-gpu-kms.h"
#define META_TYPE_DRM_BUFFER_GBM (meta_drm_buffer_gbm_get_type ())
G_DECLARE_FINAL_TYPE (MetaDrmBufferGbm,
meta_drm_buffer_gbm,
META, DRM_BUFFER_GBM,
MetaDrmBuffer)
MetaDrmBufferGbm * meta_drm_buffer_gbm_new (MetaGpuKms *gpu_kms,
struct gbm_surface *gbm_surface,
gboolean use_modifiers,
GError **error);
struct gbm_bo * meta_drm_buffer_gbm_get_bo (MetaDrmBufferGbm *buffer_gbm);
#endif /* META_DRM_BUFFER_GBM_H */

View File

@ -0,0 +1,45 @@
/*
* Copyright (C) 2011 Intel Corporation.
* Copyright (C) 2016 Red Hat
* Copyright (C) 2018 DisplayLink (UK) Ltd.
* Copyright (C) 2018 Canonical Ltd.
*
* 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.
*
* Author: Daniel van Vugt <daniel.van.vugt@canonical.com>
*/
#include "config.h"
#include "backends/native/meta-drm-buffer.h"
G_DEFINE_ABSTRACT_TYPE (MetaDrmBuffer, meta_drm_buffer, G_TYPE_OBJECT)
uint32_t
meta_drm_buffer_get_fb_id (MetaDrmBuffer *buffer)
{
return META_DRM_BUFFER_GET_CLASS (buffer)->get_fb_id (buffer);
}
static void
meta_drm_buffer_init (MetaDrmBuffer *buffer)
{
}
static void
meta_drm_buffer_class_init (MetaDrmBufferClass *klass)
{
}

View File

@ -0,0 +1,46 @@
/*
* Copyright (C) 2018 Canonical Ltd.
*
* 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.
*
* Author: Daniel van Vugt <daniel.van.vugt@canonical.com>
*/
#ifndef META_DRM_BUFFER_H
#define META_DRM_BUFFER_H
#include <glib-object.h>
#include <stdint.h>
#define META_TYPE_DRM_BUFFER (meta_drm_buffer_get_type ())
G_DECLARE_DERIVABLE_TYPE (MetaDrmBuffer,
meta_drm_buffer,
META, DRM_BUFFER,
GObject)
struct _MetaDrmBufferClass
{
GObjectClass parent_class;
uint32_t (* get_fb_id) (MetaDrmBuffer *buffer);
};
MetaDrmBuffer *
meta_drm_buffer_new_from_dumb (uint32_t dumb_fb_id);
uint32_t meta_drm_buffer_get_fb_id (MetaDrmBuffer *buffer);
#endif /* META_DRM_BUFFER_H */

View File

@ -251,13 +251,15 @@ get_session_proxy (GCancellable *cancellable,
}
static Login1Seat *
get_seat_proxy (GCancellable *cancellable,
get_seat_proxy (gchar *seat_id,
GCancellable *cancellable,
GError **error)
{
g_autofree char *seat_proxy_path = get_escaped_dbus_path ("/org/freedesktop/login1/seat", seat_id);
Login1Seat *seat = login1_seat_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
"org.freedesktop.login1",
"/org/freedesktop/login1/seat/self",
seat_proxy_path,
cancellable, error);
if (!seat)
g_prefix_error(error, "Could not get seat proxy: ");
@ -511,7 +513,7 @@ meta_launcher_new (GError **error)
if (!seat_id)
goto fail;
seat_proxy = get_seat_proxy (NULL, error);
seat_proxy = get_seat_proxy (seat_id, NULL, error);
if (!seat_proxy)
goto fail;

View File

@ -58,6 +58,9 @@
#include "backends/meta-output.h"
#include "backends/meta-renderer-view.h"
#include "backends/native/meta-crtc-kms.h"
#include "backends/native/meta-drm-buffer-dumb.h"
#include "backends/native/meta-drm-buffer-gbm.h"
#include "backends/native/meta-drm-buffer.h"
#include "backends/native/meta-gpu-kms.h"
#include "backends/native/meta-monitor-manager-kms.h"
#include "backends/native/meta-renderer-native-gles3.h"
@ -144,10 +147,8 @@ typedef struct _MetaOnscreenNativeSecondaryGpuState
struct {
struct gbm_surface *surface;
uint32_t current_fb_id;
uint32_t next_fb_id;
struct gbm_bo *current_bo;
struct gbm_bo *next_bo;
MetaDrmBuffer *current_fb;
MetaDrmBuffer *next_fb;
} gbm;
struct {
@ -168,10 +169,8 @@ typedef struct _MetaOnscreenNative
struct {
struct gbm_surface *surface;
uint32_t current_fb_id;
uint32_t next_fb_id;
struct gbm_bo *current_bo;
struct gbm_bo *next_bo;
MetaDrmBuffer *current_fb;
MetaDrmBuffer *next_fb;
} gbm;
#ifdef HAVE_EGL_DEVICE
@ -971,25 +970,12 @@ free_current_secondary_bo (MetaGpuKms *gpu_kms,
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state)
{
MetaRendererNativeGpuData *renderer_gpu_data;
int kms_fd;
kms_fd = meta_gpu_kms_get_fd (gpu_kms);
renderer_gpu_data = secondary_gpu_state->renderer_gpu_data;
switch (renderer_gpu_data->secondary.copy_mode)
{
case META_SHARED_FRAMEBUFFER_COPY_MODE_GPU:
if (secondary_gpu_state->gbm.current_fb_id)
{
drmModeRmFB (kms_fd, secondary_gpu_state->gbm.current_fb_id);
secondary_gpu_state->gbm.current_fb_id = 0;
}
if (secondary_gpu_state->gbm.current_bo)
{
gbm_surface_release_buffer (secondary_gpu_state->gbm.surface,
secondary_gpu_state->gbm.current_bo);
secondary_gpu_state->gbm.current_bo = NULL;
}
g_clear_object (&secondary_gpu_state->gbm.current_fb);
break;
case META_SHARED_FRAMEBUFFER_COPY_MODE_CPU:
break;
@ -1001,22 +987,8 @@ free_current_bo (CoglOnscreen *onscreen)
{
CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
MetaGpuKms *render_gpu = onscreen_native->render_gpu;
int kms_fd;
kms_fd = meta_gpu_kms_get_fd (render_gpu);
if (onscreen_native->gbm.current_fb_id)
{
drmModeRmFB (kms_fd, onscreen_native->gbm.current_fb_id);
onscreen_native->gbm.current_fb_id = 0;
}
if (onscreen_native->gbm.current_bo)
{
gbm_surface_release_buffer (onscreen_native->gbm.surface,
onscreen_native->gbm.current_bo);
onscreen_native->gbm.current_bo = NULL;
}
g_clear_object (&onscreen_native->gbm.current_fb);
g_hash_table_foreach (onscreen_native->secondary_gpu_states,
(GHFunc) free_current_secondary_bo,
@ -1310,11 +1282,9 @@ static void
swap_secondary_drm_fb (MetaGpuKms *gpu_kms,
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state)
{
secondary_gpu_state->gbm.current_fb_id = secondary_gpu_state->gbm.next_fb_id;
secondary_gpu_state->gbm.next_fb_id = 0;
secondary_gpu_state->gbm.current_bo = secondary_gpu_state->gbm.next_bo;
secondary_gpu_state->gbm.next_bo = NULL;
g_set_object (&secondary_gpu_state->gbm.current_fb,
secondary_gpu_state->gbm.next_fb);
g_clear_object (&secondary_gpu_state->gbm.next_fb);
}
static void
@ -1325,11 +1295,8 @@ meta_onscreen_native_swap_drm_fb (CoglOnscreen *onscreen)
free_current_bo (onscreen);
onscreen_native->gbm.current_fb_id = onscreen_native->gbm.next_fb_id;
onscreen_native->gbm.next_fb_id = 0;
onscreen_native->gbm.current_bo = onscreen_native->gbm.next_bo;
onscreen_native->gbm.next_bo = NULL;
g_set_object (&onscreen_native->gbm.current_fb, onscreen_native->gbm.next_fb);
g_clear_object (&onscreen_native->gbm.next_fb);
g_hash_table_foreach (onscreen_native->secondary_gpu_states,
(GHFunc) swap_secondary_drm_fb,
@ -1413,17 +1380,7 @@ free_next_secondary_bo (MetaGpuKms *gpu_kms,
switch (renderer_gpu_data->secondary.copy_mode)
{
case META_SHARED_FRAMEBUFFER_COPY_MODE_GPU:
if (secondary_gpu_state->gbm.next_fb_id)
{
int kms_fd;
kms_fd = meta_gpu_kms_get_fd (gpu_kms);
drmModeRmFB (kms_fd, secondary_gpu_state->gbm.next_fb_id);
gbm_surface_release_buffer (secondary_gpu_state->gbm.surface,
secondary_gpu_state->gbm.next_bo);
secondary_gpu_state->gbm.next_fb_id = 0;
secondary_gpu_state->gbm.next_bo = NULL;
}
g_clear_object (&secondary_gpu_state->gbm.next_fb);
break;
case META_SHARED_FRAMEBUFFER_COPY_MODE_CPU:
break;
@ -1448,17 +1405,7 @@ flip_closure_destroyed (MetaRendererView *view)
switch (renderer_gpu_data->mode)
{
case META_RENDERER_NATIVE_MODE_GBM:
if (onscreen_native->gbm.next_fb_id)
{
int kms_fd;
kms_fd = meta_gpu_kms_get_fd (render_gpu);
drmModeRmFB (kms_fd, onscreen_native->gbm.next_fb_id);
gbm_surface_release_buffer (onscreen_native->gbm.surface,
onscreen_native->gbm.next_bo);
onscreen_native->gbm.next_bo = NULL;
onscreen_native->gbm.next_fb_id = 0;
}
g_clear_object (&onscreen_native->gbm.next_fb);
g_hash_table_foreach (onscreen_native->secondary_gpu_states,
(GHFunc) free_next_secondary_bo,
@ -1808,12 +1755,12 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
case META_RENDERER_NATIVE_MODE_GBM:
if (gpu_kms == render_gpu)
{
fb_id = onscreen_native->gbm.next_fb_id;
fb_id = meta_drm_buffer_get_fb_id (onscreen_native->gbm.next_fb);
}
else
{
secondary_gpu_state = get_secondary_gpu_state (onscreen, gpu_kms);
fb_id = secondary_gpu_state->gbm.next_fb_id;
fb_id = meta_drm_buffer_get_fb_id (secondary_gpu_state->gbm.next_fb);
}
if (!meta_gpu_kms_flip_crtc (gpu_kms,
@ -1879,7 +1826,7 @@ set_crtc_fb (CoglOnscreen *onscreen,
if (!secondary_gpu_state)
return;
fb_id = secondary_gpu_state->gbm.next_fb_id;
fb_id = meta_drm_buffer_get_fb_id (secondary_gpu_state->gbm.next_fb);
}
x = crtc->rect.x - logical_monitor->rect.x;
@ -1922,7 +1869,7 @@ meta_onscreen_native_set_crtc_modes (CoglOnscreen *onscreen)
switch (renderer_gpu_data->mode)
{
case META_RENDERER_NATIVE_MODE_GBM:
fb_id = onscreen_native->gbm.next_fb_id;
fb_id = meta_drm_buffer_get_fb_id (onscreen_native->gbm.next_fb);
break;
#ifdef HAVE_EGL_DEVICE
case META_RENDERER_NATIVE_MODE_EGL_DEVICE:
@ -1990,7 +1937,7 @@ crtc_mode_set_fallback (CoglOnscreen *onscreen,
return FALSE;
}
fb_id = onscreen_native->gbm.next_fb_id;
fb_id = meta_drm_buffer_get_fb_id (onscreen_native->gbm.next_fb);
set_crtc_fb (onscreen, logical_monitor, crtc, fb_id);
return TRUE;
}
@ -2090,101 +2037,6 @@ meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen)
g_closure_unref (flip_closure);
}
static gboolean
gbm_get_next_fb_id (MetaGpuKms *gpu_kms,
struct gbm_surface *gbm_surface,
struct gbm_bo **out_next_bo,
uint32_t *out_next_fb_id)
{
MetaRendererNative *renderer_native = meta_renderer_native_from_gpu (gpu_kms);
struct gbm_bo *next_bo;
uint32_t next_fb_id;
int kms_fd;
uint32_t handles[4] = { 0, };
uint32_t strides[4] = { 0, };
uint32_t offsets[4] = { 0, };
uint64_t modifiers[4] = { 0, };
int i;
/* Now we need to set the CRTC to whatever is the front buffer */
next_bo = gbm_surface_lock_front_buffer (gbm_surface);
if (!next_bo)
{
g_error ("Impossible to lock surface front buffer: %m");
return FALSE;
}
if (gbm_bo_get_handle_for_plane (next_bo, 0).s32 == -1)
{
/* Failed to fetch handle to plane, falling back to old method */
strides[0] = gbm_bo_get_stride (next_bo);
handles[0] = gbm_bo_get_handle (next_bo).u32;
offsets[0] = 0;
modifiers[0] = DRM_FORMAT_MOD_INVALID;
}
else
{
for (i = 0; i < gbm_bo_get_plane_count (next_bo); i++)
{
strides[i] = gbm_bo_get_stride_for_plane (next_bo, i);
handles[i] = gbm_bo_get_handle_for_plane (next_bo, i).u32;
offsets[i] = gbm_bo_get_offset (next_bo, i);
modifiers[i] = gbm_bo_get_modifier (next_bo);
}
}
kms_fd = meta_gpu_kms_get_fd (gpu_kms);
if (renderer_native->use_modifiers &&
modifiers[0] != DRM_FORMAT_MOD_INVALID)
{
if (drmModeAddFB2WithModifiers (kms_fd,
gbm_bo_get_width (next_bo),
gbm_bo_get_height (next_bo),
gbm_bo_get_format (next_bo),
handles,
strides,
offsets,
modifiers,
&next_fb_id,
DRM_MODE_FB_MODIFIERS))
{
g_warning ("Failed to create new back buffer handle: %m");
gbm_surface_release_buffer (gbm_surface, next_bo);
return FALSE;
}
}
else if (drmModeAddFB2 (kms_fd,
gbm_bo_get_width (next_bo),
gbm_bo_get_height (next_bo),
gbm_bo_get_format (next_bo),
handles,
strides,
offsets,
&next_fb_id,
0))
{
if (drmModeAddFB (kms_fd,
gbm_bo_get_width (next_bo),
gbm_bo_get_height (next_bo),
24, /* depth */
32, /* bpp */
strides[0],
handles[0],
&next_fb_id))
{
g_warning ("Failed to create new back buffer handle: %m");
gbm_surface_release_buffer (gbm_surface, next_bo);
return FALSE;
}
}
*out_next_bo = next_bo;
*out_next_fb_id = next_fb_id;
return TRUE;
}
static void
wait_for_pending_flips (CoglOnscreen *onscreen)
{
@ -2217,6 +2069,8 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native;
MetaEgl *egl = meta_renderer_native_get_egl (renderer_native);
GError *error = NULL;
MetaDrmBufferGbm *buffer_gbm;
struct gbm_bo *bo;
if (!meta_egl_make_current (egl,
renderer_gpu_data->egl_display,
@ -2232,12 +2086,14 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
*egl_context_changed = TRUE;
buffer_gbm = META_DRM_BUFFER_GBM (onscreen_native->gbm.next_fb);
bo = meta_drm_buffer_gbm_get_bo (buffer_gbm);
if (!meta_renderer_native_gles3_blit_shared_bo (egl,
renderer_native->gles3,
renderer_gpu_data->egl_display,
renderer_gpu_data->secondary.egl_context,
secondary_gpu_state->egl_surface,
onscreen_native->gbm.next_bo,
bo,
&error))
{
g_warning ("Failed to blit shared framebuffer: %s", error->message);
@ -2255,10 +2111,19 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
return;
}
gbm_get_next_fb_id (secondary_gpu_state->gpu_kms,
secondary_gpu_state->gbm.surface,
&secondary_gpu_state->gbm.next_bo,
&secondary_gpu_state->gbm.next_fb_id);
g_clear_object (&secondary_gpu_state->gbm.next_fb);
buffer_gbm = meta_drm_buffer_gbm_new (secondary_gpu_state->gpu_kms,
secondary_gpu_state->gbm.surface,
renderer_native->use_modifiers,
&error);
secondary_gpu_state->gbm.next_fb = META_DRM_BUFFER (buffer_gbm);
if (!secondary_gpu_state->gbm.next_fb)
{
g_warning ("meta_drm_buffer_gbm_new failed: %s",
error->message);
g_error_free (error);
return;
}
}
typedef struct _PixelFormatMap {
@ -2337,6 +2202,7 @@ copy_shared_framebuffer_cpu (CoglOnscreen *onscreen,
CoglBitmap *dumb_bitmap;
CoglPixelFormat cogl_format;
gboolean ret;
MetaDrmBufferDumb *buffer_dumb;
width = cogl_framebuffer_get_width (framebuffer);
height = cogl_framebuffer_get_height (framebuffer);
@ -2377,7 +2243,9 @@ copy_shared_framebuffer_cpu (CoglOnscreen *onscreen,
cogl_object_unref (dumb_bitmap);
secondary_gpu_state->gbm.next_fb_id = target_fb_id;
g_clear_object (&secondary_gpu_state->gbm.next_fb);
buffer_dumb = meta_drm_buffer_dumb_new (target_fb_id);
secondary_gpu_state->gbm.next_fb = META_DRM_BUFFER (buffer_dumb);
}
static void
@ -2464,6 +2332,8 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
CoglFrameInfo *frame_info;
gboolean egl_context_changed = FALSE;
MetaPowerSave power_save_mode;
g_autoptr (GError) error = NULL;
MetaDrmBufferGbm *buffer_gbm;
/*
* Wait for the flip callback before continuing, as we might have started the
@ -2485,14 +2355,20 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
switch (renderer_gpu_data->mode)
{
case META_RENDERER_NATIVE_MODE_GBM:
g_warn_if_fail (onscreen_native->gbm.next_bo == NULL &&
onscreen_native->gbm.next_fb_id == 0);
g_warn_if_fail (onscreen_native->gbm.next_fb == NULL);
g_clear_object (&onscreen_native->gbm.next_fb);
if (!gbm_get_next_fb_id (render_gpu,
onscreen_native->gbm.surface,
&onscreen_native->gbm.next_bo,
&onscreen_native->gbm.next_fb_id))
return;
buffer_gbm = meta_drm_buffer_gbm_new (render_gpu,
onscreen_native->gbm.surface,
renderer_native->use_modifiers,
&error);
onscreen_native->gbm.next_fb = META_DRM_BUFFER (buffer_gbm);
if (!onscreen_native->gbm.next_fb)
{
g_warning ("meta_drm_buffer_gbm_new failed: %s",
error->message);
return;
}
break;
#ifdef HAVE_EGL_DEVICE
@ -3083,7 +2959,7 @@ meta_renderer_native_release_onscreen (CoglOnscreen *onscreen)
case META_RENDERER_NATIVE_MODE_GBM:
/* flip state takes a reference on the onscreen so there should
* never be outstanding flips when we reach here. */
g_return_if_fail (onscreen_native->gbm.next_fb_id == 0);
g_return_if_fail (onscreen_native->gbm.next_fb == NULL);
free_current_bo (onscreen);

View File

@ -851,10 +851,7 @@ meta_rectangle_expand_to_avoiding_struts (MetaRectangle *rect,
void
meta_rectangle_free_list_and_elements (GList *filled_list)
{
g_list_foreach (filled_list,
(void (*)(gpointer,gpointer))&g_free, /* ew, for ugly */
NULL);
g_list_free (filled_list);
g_list_free_full (filled_list, g_free);
}
gboolean
@ -2054,25 +2051,11 @@ meta_rectangle_scale_double (const MetaRectangle *rect,
MetaRoundingStrategy rounding_strategy,
MetaRectangle *dest)
{
switch (rounding_strategy)
{
case META_ROUNDING_STRATEGY_SHRINK:
*dest = (MetaRectangle) {
.x = (int) ceil (rect->x * scale),
.y = (int) ceil (rect->y * scale),
.width = (int) floor (rect->width * scale),
.height = (int) floor (rect->height * scale),
};
break;
case META_ROUNDING_STRATEGY_GROW:
*dest = (MetaRectangle) {
.x = (int) floor (rect->x * scale),
.y = (int) floor (rect->y * scale),
.width = (int) ceil (rect->width * scale),
.height = (int) ceil (rect->height * scale),
};
break;
}
ClutterRect tmp = CLUTTER_RECT_INIT (rect->x, rect->y,
rect->width, rect->height);
clutter_rect_scale (&tmp, scale, scale);
meta_rectangle_from_clutter_rect (&tmp, rounding_strategy, dest);
}
void
@ -2085,12 +2068,7 @@ meta_rectangle_transform (const MetaRectangle *rect,
switch (transform)
{
case META_MONITOR_TRANSFORM_NORMAL:
*dest = (MetaRectangle) {
.x = rect->x,
.y = rect->y,
.width = rect->width,
.height = rect->height,
};
*dest = *rect;
break;
case META_MONITOR_TRANSFORM_90:
*dest = (MetaRectangle) {

View File

@ -1157,13 +1157,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
g_list_free (stacked_windows);
/* Free the memory used by the obscuring windows/docks lists */
g_slist_free (window_stacking);
/* FIXME: Shouldn't there be a helper function to make this one line of code
* to free a list instead of four ugly ones?
*/
g_slist_foreach (obscuring_windows,
(void (*)(gpointer,gpointer))&g_free, /* ew, for ugly */
NULL);
g_slist_free (obscuring_windows);
g_slist_free_full (obscuring_windows, g_free);
/* Sort the list. FIXME: Should I bother with this sorting? I just
* sort again later in cache_edges() anyway...

View File

@ -622,12 +622,9 @@ meta_window_process_placement (MetaWindow *window,
window_height = placement_rule->height;
meta_window_get_frame_rect (parent, &parent_rect);
anchor_rect = (MetaRectangle) {
.x = parent_rect.x + placement_rule->anchor_rect.x,
.y = parent_rect.y + placement_rule->anchor_rect.y,
.width = placement_rule->anchor_rect.width,
.height = placement_rule->anchor_rect.height,
};
anchor_rect = placement_rule->anchor_rect;
anchor_rect.x += parent_rect.x;
anchor_rect.y += parent_rect.y;
/* Place at anchor point. */
if (placement_rule->anchor & META_PLACEMENT_ANCHOR_LEFT)

View File

@ -575,8 +575,7 @@ meta_startup_notification_finalize (GObject *object)
if (sn->startup_sequence_timeout)
g_source_remove (sn->startup_sequence_timeout);
g_slist_foreach (sn->startup_sequences, (GFunc) g_object_unref, NULL);
g_slist_free (sn->startup_sequences);
g_slist_free_full (sn->startup_sequences, g_object_unref);
sn->startup_sequences = NULL;
G_OBJECT_CLASS (meta_startup_notification_parent_class)->finalize (object);

View File

@ -241,20 +241,6 @@ utf8_fputs (const char *str,
return retval;
}
/**
* meta_free_gslist_and_elements: (skip)
* @list_to_deep_free: list to deep free
*
*/
void
meta_free_gslist_and_elements (GSList *list_to_deep_free)
{
g_slist_foreach (list_to_deep_free,
(void (*)(gpointer,gpointer))&g_free, /* ew, for ugly */
NULL);
g_slist_free (list_to_deep_free);
}
#ifdef WITH_VERBOSE_MODE
void
meta_debug_spew_real (const char *format, ...)

View File

@ -1525,7 +1525,7 @@ meta_window_unmanage (MetaWindow *window,
if (window->struts)
{
meta_free_gslist_and_elements (window->struts);
g_slist_free_full (window->struts, g_free);
window->struts = NULL;
meta_topic (META_DEBUG_WORKAREA,

View File

@ -52,8 +52,6 @@ void meta_workspace_queue_calc_showing (MetaWorkspace *workspace);
static void focus_ancestor_or_top_window (MetaWorkspace *workspace,
MetaWindow *not_this_one,
guint32 timestamp);
static void free_this (gpointer candidate,
gpointer dummy);
G_DEFINE_TYPE (MetaWorkspace, meta_workspace, G_TYPE_OBJECT);
@ -265,13 +263,6 @@ meta_workspace_new (MetaWorkspaceManager *workspace_manager)
return workspace;
}
/* Foreach function for workspace_free_struts() */
static void
free_this (gpointer candidate, gpointer dummy)
{
g_free (candidate);
}
/**
* workspace_free_all_struts:
* @workspace: The workspace.
@ -284,8 +275,7 @@ workspace_free_all_struts (MetaWorkspace *workspace)
if (workspace->all_struts == NULL)
return;
g_slist_foreach (workspace->all_struts, free_this, NULL);
g_slist_free (workspace->all_struts);
g_slist_free_full (workspace->all_struts, g_free);
workspace->all_struts = NULL;
}
@ -301,8 +291,7 @@ workspace_free_builtin_struts (MetaWorkspace *workspace)
if (workspace->builtin_struts == NULL)
return;
g_slist_foreach (workspace->builtin_struts, free_this, NULL);
g_slist_free (workspace->builtin_struts);
g_slist_free_full (workspace->builtin_struts, g_free);
workspace->builtin_struts = NULL;
}

View File

@ -574,6 +574,12 @@ if have_native_backend
'backends/native/meta-crtc-kms.h',
'backends/native/meta-cursor-renderer-native.c',
'backends/native/meta-cursor-renderer-native.h',
'backends/native/meta-drm-buffer-dumb.c',
'backends/native/meta-drm-buffer-dumb.h',
'backends/native/meta-drm-buffer-gbm.c',
'backends/native/meta-drm-buffer-gbm.h',
'backends/native/meta-drm-buffer.c',
'backends/native/meta-drm-buffer.h',
'backends/native/meta-gpu-kms.c',
'backends/native/meta-gpu-kms.h',
'backends/native/meta-input-settings-native.c',

View File

@ -149,9 +149,6 @@ char* meta_external_binding_name_for_action (guint keybinding_action);
META_EXPORT
char* meta_g_utf8_strndup (const gchar *src, gsize n);
META_EXPORT
void meta_free_gslist_and_elements (GSList *list_to_deep_free);
META_EXPORT
GPid meta_show_dialog (const char *type,
const char *message,

View File

@ -121,6 +121,7 @@
<arg name="dy" type="d" direction="in" />
<arg name="flags" type="u" direction="in" />
</method>
<!--
NotifyPointerAxisDiscrete:
@ -134,7 +135,7 @@
<!--
NotifyPointerMotionRelative:
A absolute pointer motion event notification
A relative pointer motion event notification
-->
<method name="NotifyPointerMotionRelative">
<arg name="dx" type="d" direction="in" />

View File

@ -221,13 +221,7 @@ test_basic_fitting (void)
static void
free_strut_list (GSList *struts)
{
GSList *tmp = struts;
while (tmp)
{
g_free (tmp->data);
tmp = tmp->next;
}
g_slist_free (struts);
g_slist_free_full (struts, g_free);
}
static GSList*

View File

@ -249,7 +249,7 @@ source_new_cb (GObject *object,
MetaSelection *selection = data->selection;
MetaSelectionType selection_type = data->selection_type;
MetaX11Display *x11_display = data->x11_display;
GError *error = NULL;
g_autoptr (GError) error = NULL;
source = meta_selection_source_x11_new_finish (res, &error);
if (source)
@ -257,7 +257,7 @@ source_new_cb (GObject *object,
meta_selection_set_owner (selection, selection_type, source);
g_set_object (&x11_display->selection.owners[selection_type], source);
}
else
else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
{
g_warning ("Could not create selection source for X11: %s",
error->message);

View File

@ -1559,7 +1559,7 @@ meta_window_x11_update_struts (MetaWindow *window)
changed = (old_iter != NULL || new_iter != NULL);
/* Update appropriately */
meta_free_gslist_and_elements (old_struts);
g_slist_free_full (old_struts, g_free);
window->struts = new_struts;
return changed;
}