Compare commits

..

2 Commits

Author SHA1 Message Date
Niels De Graef
83fd21f759 docs: Re-enable generating the reference manual
gtk-doc support was removed around 3 years ago with commit 7dc0b0e6.
Now that we have Meson and [MRs related to documentation], it makes
sense to re-enable this, so people who want to use libmutter can do so
without having to actually dive in the code.

[MRs related to documentation]: https://gitlab.gnome.org/GNOME/mutter/merge_requests/269
2019-04-08 11:42:13 +02:00
Niels De Graef
46453c7a7d skip MetaWaylandFrameCallback for gtk-doc
gtk-doc has a bug in its parser where it doesn't allow the first field
of a struct to have something of the form `struct foo bar;`.

See also https://github.com/GNOME/gtk-doc/blob/master/gtkdoc/common.py#L236
2019-04-08 09:57:21 +02:00
52 changed files with 1223 additions and 689 deletions

30
NEWS
View File

@@ -1,33 +1,3 @@
3.32.1
======
* Fix fallback app menu on wayland [Florian; #493]
* Fix elogind support [Tom; !491]
* Fix startup notifications not timing out [Carlos; #501]
* Fix keyboard accessibility toggle from keys
[Olivier, Carlos; !501, #529, !531]
* Fix touchscreen input on rotated displays [Carlos; #514]
* Work around hangul text input bug [Carlos; #1365]
* Fix blurry wallpaper scaling [Daniel; !505]
* Fix placement of window menu when using fractional scaling [Jan; #527]
* Fix repaint issues of offscreen effects on secondary monitors [Daniel; !511]
* Fix windows not getting focus after launch [Daniel; #505]
* Properly advertise support for 'underscan' property [Jonas; !507]
* Improve power-saving handling [Jonas; !506]
* Fix moving windows by super+touch [Jonas D.; !495]
* Misc. bug fixes and cleanups [Benjamin, Florian, Adam, Marco, Pablo,
Erik, Jonas, Heiher, Pekka, Daniel, Olivier, Carlos; !478, !475, !480,
!482, #490, !488, #491, #480, !477, !496, !492, !485, !515, !519, !521,
!216, !538, #541, #523]
Contributors:
Jonas Ådahl, Pablo Barciela, Benjamin Berg, Tom Briden, Jonas Dreßler,
Olivier Fourdan, Carlos Garnacho, Jan Alexander Steffens (heftig), Heiher,
Adam Jackson, Erik Kurzinger, Florian Müllner, Pekka Paalanen,
Marco Trevisan (Treviño), Daniel van Vugt
Translators:
Khaled Hosny [ar], Goran Vidović [hr], Daniel Mustieles [es]
3.32.0
======
* Fix deadlock when cancelling a theme sound [Andrea; !474]

View File

@@ -6,6 +6,46 @@
G_BEGIN_DECLS
typedef enum
{
CLUTTER_DEBUG_MISC = 1 << 0,
CLUTTER_DEBUG_ACTOR = 1 << 1,
CLUTTER_DEBUG_TEXTURE = 1 << 2,
CLUTTER_DEBUG_EVENT = 1 << 3,
CLUTTER_DEBUG_PAINT = 1 << 4,
CLUTTER_DEBUG_PANGO = 1 << 5,
CLUTTER_DEBUG_BACKEND = 1 << 6,
CLUTTER_DEBUG_SCHEDULER = 1 << 7,
CLUTTER_DEBUG_SCRIPT = 1 << 8,
CLUTTER_DEBUG_SHADER = 1 << 9,
CLUTTER_DEBUG_MULTISTAGE = 1 << 10,
CLUTTER_DEBUG_ANIMATION = 1 << 11,
CLUTTER_DEBUG_LAYOUT = 1 << 12,
CLUTTER_DEBUG_PICK = 1 << 13,
CLUTTER_DEBUG_EVENTLOOP = 1 << 14,
CLUTTER_DEBUG_CLIPPING = 1 << 15,
CLUTTER_DEBUG_OOB_TRANSFORMS = 1 << 16
} ClutterDebugFlag;
typedef enum
{
CLUTTER_DEBUG_NOP_PICKING = 1 << 0,
CLUTTER_DEBUG_DUMP_PICK_BUFFERS = 1 << 1
} ClutterPickDebugFlag;
typedef enum
{
CLUTTER_DEBUG_DISABLE_SWAP_EVENTS = 1 << 0,
CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS = 1 << 1,
CLUTTER_DEBUG_REDRAWS = 1 << 2,
CLUTTER_DEBUG_PAINT_VOLUMES = 1 << 3,
CLUTTER_DEBUG_DISABLE_CULLING = 1 << 4,
CLUTTER_DEBUG_DISABLE_OFFSCREEN_REDIRECT = 1 << 5,
CLUTTER_DEBUG_CONTINUOUS_REDRAW = 1 << 6,
CLUTTER_DEBUG_PAINT_DEFORM_TILES = 1 << 7,
CLUTTER_DEBUG_PAINT_DAMAGE_REGION = 1 << 8,
} ClutterDrawDebugFlag;
#ifdef CLUTTER_ENABLE_DEBUG
#define CLUTTER_HAS_DEBUG(type) ((clutter_debug_flags & CLUTTER_DEBUG_##type) != FALSE)

View File

@@ -550,7 +550,13 @@ static gboolean
are_kbd_a11y_settings_equal (ClutterKbdA11ySettings *a,
ClutterKbdA11ySettings *b)
{
return (memcmp (a, b, sizeof (ClutterKbdA11ySettings)) == 0);
return (a->controls == b->controls &&
a->slowkeys_delay == b->slowkeys_delay &&
a->debounce_delay == b->debounce_delay &&
a->timeout_delay == b->timeout_delay &&
a->mousekeys_init_delay == b->mousekeys_init_delay &&
a->mousekeys_max_speed == b->mousekeys_max_speed &&
a->mousekeys_accel_time == b->mousekeys_accel_time);
}
void

View File

@@ -89,6 +89,7 @@ static GCallback clutter_threads_unlock = NULL;
/* command line options */
static gboolean clutter_is_initialized = FALSE;
static gboolean clutter_show_fps = FALSE;
static gboolean clutter_fatal_warnings = FALSE;
static gboolean clutter_disable_mipmap_text = FALSE;
static gboolean clutter_use_fuzzy_picking = FALSE;
@@ -124,7 +125,6 @@ static const GDebugKey clutter_debug_keys[] = {
{ "layout", CLUTTER_DEBUG_LAYOUT },
{ "clipping", CLUTTER_DEBUG_CLIPPING },
{ "oob-transforms", CLUTTER_DEBUG_OOB_TRANSFORMS },
{ "frame-time", CLUTTER_DEBUG_FRAME_TIME },
};
#endif /* CLUTTER_ENABLE_DEBUG */
@@ -143,7 +143,6 @@ static const GDebugKey clutter_paint_debug_keys[] = {
{ "continuous-redraw", CLUTTER_DEBUG_CONTINUOUS_REDRAW },
{ "paint-deform-tiles", CLUTTER_DEBUG_PAINT_DEFORM_TILES },
{ "damage-region", CLUTTER_DEBUG_PAINT_DAMAGE_REGION },
{ "frame-time", CLUTTER_DEBUG_PAINT_FRAME_TIME },
};
static void
@@ -205,6 +204,16 @@ clutter_config_read_from_key_file (GKeyFile *keyfile)
g_free (str_value);
bool_value =
g_key_file_get_boolean (keyfile, ENVIRONMENT_GROUP,
"ShowFps",
&key_error);
if (key_error != NULL)
g_clear_error (&key_error);
else
clutter_show_fps = bool_value;
bool_value =
g_key_file_get_boolean (keyfile, ENVIRONMENT_GROUP,
"DisableMipmappedText",
@@ -373,6 +382,36 @@ clutter_config_read (void)
g_free (config_path);
}
/**
* clutter_get_show_fps:
*
* Returns whether Clutter should print out the frames per second on the
* console. You can enable this setting either using the
* <literal>CLUTTER_SHOW_FPS</literal> environment variable or passing
* the <literal>--clutter-show-fps</literal> command line argument. *
*
* Return value: %TRUE if Clutter should show the FPS.
*
* Since: 0.4
*
* Deprecated: 1.10: This function does not do anything. Use the environment
* variable or the configuration file to determine whether Clutter should
* print out the FPS counter on the console.
*/
gboolean
clutter_get_show_fps (void)
{
return FALSE;
}
gboolean
_clutter_context_get_show_fps (void)
{
ClutterMainContext *context = _clutter_context_get_default ();
return context->show_fps;
}
/**
* clutter_get_accessibility_enabled:
*
@@ -1331,6 +1370,8 @@ clutter_init_real (GError **error)
}
static GOptionEntry clutter_args[] = {
{ "clutter-show-fps", 0, 0, G_OPTION_ARG_NONE, &clutter_show_fps,
N_("Show frames per second"), NULL },
{ "clutter-default-fps", 0, 0, G_OPTION_ARG_INT, &clutter_default_fps,
N_("Default frame rate"), "FPS" },
{ "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &clutter_fatal_warnings,
@@ -1409,6 +1450,10 @@ pre_parse_hook (GOptionContext *context,
env_string = NULL;
}
env_string = g_getenv ("CLUTTER_SHOW_FPS");
if (env_string)
clutter_show_fps = TRUE;
env_string = g_getenv ("CLUTTER_DEFAULT_FPS");
if (env_string)
{
@@ -1457,6 +1502,7 @@ post_parse_hook (GOptionContext *context,
}
clutter_context->frame_rate = clutter_default_fps;
clutter_context->show_fps = clutter_show_fps;
clutter_context->options_parsed = TRUE;
/* If not asked to defer display setup, call clutter_init_real(),
@@ -3558,36 +3604,6 @@ clutter_check_windowing_backend (const char *backend_type)
return FALSE;
}
/**
* clutter_add_debug_flags: (skip)
*
* Adds the debug flags passed to the list of debug flags.
*/
void
clutter_add_debug_flags (ClutterDebugFlag debug_flags,
ClutterDrawDebugFlag draw_flags,
ClutterPickDebugFlag pick_flags)
{
clutter_debug_flags |= debug_flags;
clutter_paint_debug_flags |= draw_flags;
clutter_pick_debug_flags |= pick_flags;
}
/**
* clutter_remove_debug_flags: (skip)
*
* Removes the debug flags passed from the list of debug flags.
*/
void
clutter_remove_debug_flags (ClutterDebugFlag debug_flags,
ClutterDrawDebugFlag draw_flags,
ClutterPickDebugFlag pick_flags)
{
clutter_debug_flags &= ~debug_flags;
clutter_paint_debug_flags &= ~draw_flags;
clutter_pick_debug_flags &= ~pick_flags;
}
void
_clutter_set_sync_to_vblank (gboolean sync_to_vblank)
{

View File

@@ -34,49 +34,6 @@
G_BEGIN_DECLS
typedef enum
{
CLUTTER_DEBUG_MISC = 1 << 0,
CLUTTER_DEBUG_ACTOR = 1 << 1,
CLUTTER_DEBUG_TEXTURE = 1 << 2,
CLUTTER_DEBUG_EVENT = 1 << 3,
CLUTTER_DEBUG_PAINT = 1 << 4,
CLUTTER_DEBUG_PANGO = 1 << 5,
CLUTTER_DEBUG_BACKEND = 1 << 6,
CLUTTER_DEBUG_SCHEDULER = 1 << 7,
CLUTTER_DEBUG_SCRIPT = 1 << 8,
CLUTTER_DEBUG_SHADER = 1 << 9,
CLUTTER_DEBUG_MULTISTAGE = 1 << 10,
CLUTTER_DEBUG_ANIMATION = 1 << 11,
CLUTTER_DEBUG_LAYOUT = 1 << 12,
CLUTTER_DEBUG_PICK = 1 << 13,
CLUTTER_DEBUG_EVENTLOOP = 1 << 14,
CLUTTER_DEBUG_CLIPPING = 1 << 15,
CLUTTER_DEBUG_OOB_TRANSFORMS = 1 << 16,
CLUTTER_DEBUG_FRAME_TIME = 1 << 17,
} ClutterDebugFlag;
typedef enum
{
CLUTTER_DEBUG_NOP_PICKING = 1 << 0,
CLUTTER_DEBUG_DUMP_PICK_BUFFERS = 1 << 1
} ClutterPickDebugFlag;
typedef enum
{
CLUTTER_DEBUG_DISABLE_SWAP_EVENTS = 1 << 0,
CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS = 1 << 1,
CLUTTER_DEBUG_REDRAWS = 1 << 2,
CLUTTER_DEBUG_PAINT_VOLUMES = 1 << 3,
CLUTTER_DEBUG_DISABLE_CULLING = 1 << 4,
CLUTTER_DEBUG_DISABLE_OFFSCREEN_REDIRECT = 1 << 5,
CLUTTER_DEBUG_CONTINUOUS_REDRAW = 1 << 6,
CLUTTER_DEBUG_PAINT_DEFORM_TILES = 1 << 7,
CLUTTER_DEBUG_PAINT_DAMAGE_REGION = 1 << 8,
CLUTTER_DEBUG_PAINT_FRAME_TIME = 1 << 9,
} ClutterDrawDebugFlag;
/**
* CLUTTER_INIT_ERROR:
*
@@ -217,15 +174,6 @@ guint clutter_get_default_frame_rate (void);
CLUTTER_EXPORT
gboolean clutter_check_windowing_backend (const char *backend_type);
CLUTTER_EXPORT
void clutter_add_debug_flags (ClutterDebugFlag debug_flags,
ClutterDrawDebugFlag draw_flags,
ClutterPickDebugFlag pick_flags);
CLUTTER_EXPORT
void clutter_remove_debug_flags (ClutterDebugFlag debug_flags,
ClutterDrawDebugFlag draw_flags,
ClutterPickDebugFlag pick_flags);
G_END_DECLS

View File

@@ -176,6 +176,7 @@ struct _ClutterMainContext
guint motion_events_per_actor : 1;
guint defer_display_setup : 1;
guint options_parsed : 1;
guint show_fps : 1;
};
/* shared between clutter-main.c and clutter-frame-source.c */
@@ -201,6 +202,7 @@ void _clutter_context_push_shader_stack (Clutter
ClutterActor * _clutter_context_pop_shader_stack (ClutterActor *actor);
ClutterActor * _clutter_context_peek_shader_stack (void);
gboolean _clutter_context_get_motion_events_enabled (void);
gboolean _clutter_context_get_show_fps (void);
gboolean _clutter_feature_init (GError **error);

View File

@@ -134,12 +134,6 @@ void _clutter_stage_presented (ClutterStage *stag
GList * _clutter_stage_peek_stage_views (ClutterStage *stage);
int clutter_stage_get_sync_delay (ClutterStage *stage);
void clutter_stage_get_frame_times (ClutterStage *stage,
double *paint_time,
double *layout_time);
G_END_DECLS
#endif /* __CLUTTER_STAGE_PRIVATE_H__ */

View File

@@ -133,6 +133,9 @@ struct _ClutterStagePrivate
gint sync_delay;
GTimer *fps_timer;
gint32 timer_n_frames;
ClutterIDPool *pick_id_pool;
#ifdef CLUTTER_ENABLE_DEBUG
@@ -146,9 +149,6 @@ struct _ClutterStagePrivate
int update_freeze_count;
double last_layout_time;
double last_paint_time;
guint relayout_pending : 1;
guint redraw_pending : 1;
guint is_fullscreen : 1;
@@ -1074,15 +1074,11 @@ _clutter_stage_maybe_relayout (ClutterActor *actor)
/* avoid reentrancy */
if (!CLUTTER_ACTOR_IN_RELAYOUT (stage))
{
int64_t start, end;
priv->relayout_pending = FALSE;
priv->stage_was_relayout = TRUE;
CLUTTER_NOTE (ACTOR, "Recomputing layout");
start = g_get_monotonic_time ();
CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_IN_RELAYOUT);
natural_width = natural_height = 0;
@@ -1103,20 +1099,14 @@ _clutter_stage_maybe_relayout (ClutterActor *actor)
&box, CLUTTER_ALLOCATION_NONE);
CLUTTER_UNSET_PRIVATE_FLAGS (stage, CLUTTER_IN_RELAYOUT);
end = g_get_monotonic_time ();
priv->last_layout_time = (end - start) / 1000.0;
CLUTTER_NOTE (FRAME_TIME, "LAYOUT: %lf", priv->last_layout_time);
}
}
static void
clutter_stage_do_redraw (ClutterStage *stage)
{
ClutterActor *actor = CLUTTER_ACTOR (stage);
ClutterStagePrivate *priv = stage->priv;
int64_t start;
int64_t end;
if (CLUTTER_ACTOR_IN_DESTRUCTION (stage))
return;
@@ -1125,20 +1115,34 @@ clutter_stage_do_redraw (ClutterStage *stage)
return;
CLUTTER_NOTE (PAINT, "Redraw started for stage '%s'[%p]",
_clutter_actor_get_debug_name (CLUTTER_ACTOR (stage)),
_clutter_actor_get_debug_name (actor),
stage);
start = g_get_monotonic_time ();
if (_clutter_context_get_show_fps ())
{
if (priv->fps_timer == NULL)
priv->fps_timer = g_timer_new ();
}
_clutter_stage_window_redraw (priv->impl);
end = g_get_monotonic_time ();
if (_clutter_context_get_show_fps ())
{
priv->timer_n_frames += 1;
priv->last_paint_time = (end - start) / 1000.0;
CLUTTER_NOTE (FRAME_TIME, "PAINT: %lf", priv->last_paint_time);
if (g_timer_elapsed (priv->fps_timer, NULL) >= 1.0)
{
g_print ("*** FPS for %s: %i ***\n",
_clutter_actor_get_debug_name (actor),
priv->timer_n_frames);
priv->timer_n_frames = 0;
g_timer_start (priv->fps_timer);
}
}
CLUTTER_NOTE (PAINT, "Redraw finished for stage '%s'[%p]",
_clutter_actor_get_debug_name (CLUTTER_ACTOR (stage)),
_clutter_actor_get_debug_name (actor),
stage);
}
@@ -1882,6 +1886,9 @@ clutter_stage_finalize (GObject *object)
_clutter_id_pool_free (priv->pick_id_pool);
if (priv->fps_timer != NULL)
g_timer_destroy (priv->fps_timer);
if (priv->paint_notify != NULL)
priv->paint_notify (priv->paint_data);
@@ -4721,14 +4728,6 @@ clutter_stage_set_sync_delay (ClutterStage *stage,
stage->priv->sync_delay = sync_delay;
}
int
clutter_stage_get_sync_delay (ClutterStage *stage)
{
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), -1);
return stage->priv->sync_delay;
}
/**
* clutter_stage_skip_sync_delay:
* @stage: a #ClutterStage
@@ -5098,12 +5097,3 @@ _clutter_stage_get_max_view_scale_factor_for_rect (ClutterStage *stage,
*view_scale = scale;
return TRUE;
}
void
clutter_stage_get_frame_times (ClutterStage *stage,
double *paint_time,
double *layout_time)
{
*paint_time = stage->priv->last_paint_time;
*layout_time = stage->priv->last_layout_time;
}

View File

@@ -405,215 +405,6 @@ paint_damage_region (ClutterStageWindow *stage_window,
cogl_framebuffer_pop_matrix (framebuffer);
}
#define CHART_COLUMN_WIDTH 6 //px
#define THRESHOLD_LINE_HEIGHT 2 //px
#define MAX_FRAME_TIME_INFO_ENTRIES 1000
typedef struct
{
double layout_time;
double paint_time;
} FrameTimeInfo;
static void
get_frame_time_chart_region (ClutterStageWindow *stage_window,
ClutterStageView *view,
cairo_rectangle_int_t *region)
{
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
cairo_rectangle_int_t painted_region;
cairo_rectangle_int_t layout;
double refresh_rate_bar_height;
double ms_per_frame;
float green_line_y;
int sync_delay;
int n_points;
int i;
clutter_stage_view_get_layout (view, &layout);
painted_region = (cairo_rectangle_int_t) {
.x = layout.x,
.y = layout.y + layout.height,
.width = layout.width,
.height = 0,
};
n_points = layout.width / CHART_COLUMN_WIDTH;
/* Chart */
sync_delay = clutter_stage_get_sync_delay (stage_cogl->wrapper);
ms_per_frame = 1000.0 / stage_cogl->refresh_rate - sync_delay;
refresh_rate_bar_height = layout.height * 0.1;
for (i = 0; i < MIN (stage_cogl->frame_times->len, n_points); i++)
{
int element = stage_cogl->frame_times->len - i - 1;
FrameTimeInfo *info = &g_array_index (stage_cogl->frame_times, FrameTimeInfo, element);
double layout_bar_height;
double paint_bar_height;
/* Layout time section */
layout_bar_height =
info->layout_time / ms_per_frame * refresh_rate_bar_height;
/* Paint time section */
paint_bar_height =
info->paint_time / ms_per_frame * refresh_rate_bar_height;
painted_region.height = MAX (painted_region.height,
paint_bar_height + layout_bar_height);
}
/* Green line (16.667ms) */
green_line_y = layout.height * 0.9;
painted_region.height = MAX (painted_region.height, green_line_y);
/* Update the swap region rectangle */
painted_region.y -= MIN (layout.height, painted_region.height);
_clutter_util_rectangle_union (region, &painted_region, region);
}
static void
paint_frame_time_chart (ClutterStageWindow *stage_window,
ClutterStageView *view)
{
CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (view);
CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
ClutterActor *actor = CLUTTER_ACTOR (stage_cogl->wrapper);
cairo_rectangle_int_t layout;
static CoglPipeline *threshold_pipeline = NULL;
static CoglPipeline *paint_time_pipeline = NULL;
static CoglPipeline *layout_time_pipeline = NULL;
CoglMatrix modelview;
double refresh_rate_bar_height;
double ms_per_frame;
float green_line_y;
int sync_delay;
int n_points;
int i;
if (G_UNLIKELY (paint_time_pipeline == NULL))
{
paint_time_pipeline = cogl_pipeline_new (ctx);
cogl_pipeline_set_color4ub (paint_time_pipeline, 0x00, 0x00, 0x60, 0xa0);
}
if (G_UNLIKELY (layout_time_pipeline == NULL))
{
layout_time_pipeline = cogl_pipeline_new (ctx);
cogl_pipeline_set_color4ub (layout_time_pipeline, 0x00, 0x60, 0x00, 0xa0);
}
if (G_UNLIKELY (threshold_pipeline == NULL))
{
threshold_pipeline = cogl_pipeline_new (ctx);
cogl_pipeline_set_color4ub (threshold_pipeline, 0x40, 0x00, 0x00, 0x80);
}
cogl_framebuffer_push_matrix (framebuffer);
cogl_matrix_init_identity (&modelview);
_clutter_actor_apply_modelview_transform (actor, &modelview);
cogl_framebuffer_set_modelview_matrix (framebuffer, &modelview);
clutter_stage_view_get_layout (view, &layout);
n_points = layout.width / CHART_COLUMN_WIDTH;
/* Chart */
sync_delay = clutter_stage_get_sync_delay (stage_cogl->wrapper);
ms_per_frame = 1000.0 / stage_cogl->refresh_rate - sync_delay;
refresh_rate_bar_height = layout.height * 0.1;
for (i = 0; i < MIN (stage_cogl->frame_times->len, n_points); i++)
{
int element = stage_cogl->frame_times->len - i - 1;
FrameTimeInfo *info = &g_array_index (stage_cogl->frame_times, FrameTimeInfo, element);
double x_1 = layout.width - (i + 1) * CHART_COLUMN_WIDTH;
double x_2 = layout.width - i * CHART_COLUMN_WIDTH;
double layout_bar_height;
double paint_bar_height;
/* Layout time section */
layout_bar_height =
info->layout_time / ms_per_frame * refresh_rate_bar_height;
cogl_framebuffer_draw_rectangle (framebuffer,
layout_time_pipeline,
x_1,
layout.height - layout_bar_height,
x_2,
layout.height);
/* Paint time section */
paint_bar_height =
info->paint_time / ms_per_frame * refresh_rate_bar_height;
cogl_framebuffer_draw_rectangle (framebuffer,
paint_time_pipeline,
x_1,
layout.height - paint_bar_height - layout_bar_height,
x_2,
layout.height - layout_bar_height);
}
/* Green line (16.667ms) */
green_line_y = layout.height * 0.9;
cogl_framebuffer_draw_rectangle (framebuffer,
threshold_pipeline,
0.0f,
green_line_y,
layout.width,
green_line_y + THRESHOLD_LINE_HEIGHT);
cogl_framebuffer_pop_matrix (framebuffer);
}
static inline void
append_frame_time_info (ClutterStageCogl *stage_cogl)
{
FrameTimeInfo previous_frame_info;
if (G_LIKELY (!(clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_FRAME_TIME)))
return;
if (G_UNLIKELY (stage_cogl->frame_times == NULL))
stage_cogl->frame_times = g_array_sized_new (FALSE, TRUE,
sizeof (FrameTimeInfo),
MAX_FRAME_TIME_INFO_ENTRIES);
clutter_stage_get_frame_times (stage_cogl->wrapper,
&previous_frame_info.paint_time,
&previous_frame_info.layout_time);
g_array_append_val (stage_cogl->frame_times, previous_frame_info);
if (stage_cogl->frame_times->len > MAX_FRAME_TIME_INFO_ENTRIES)
g_array_remove_range (stage_cogl->frame_times, 0,
stage_cogl->frame_times->len - MAX_FRAME_TIME_INFO_ENTRIES);
}
static inline void
maybe_paint_frame_times (ClutterStageWindow *stage_window,
ClutterStageView *view)
{
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
if (G_UNLIKELY ((clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_FRAME_TIME)))
{
paint_frame_time_chart (stage_window, view);
stage_cogl->painting_frame_chart = TRUE;
}
else if (stage_cogl->painting_frame_chart)
{
g_array_free (stage_cogl->frame_times, TRUE);
stage_cogl->frame_times = NULL;
stage_cogl->painting_frame_chart = FALSE;
}
}
static gboolean
swap_framebuffer (ClutterStageWindow *stage_window,
ClutterStageView *view,
@@ -881,9 +672,6 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
fb_clip_region = (cairo_rectangle_int_t) { 0 };
}
if (G_UNLIKELY ((clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_FRAME_TIME)))
get_frame_time_chart_region (stage_window, view, &fb_clip_region);
if (may_use_clipped_redraw &&
G_LIKELY (!(clutter_paint_debug_flags & CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS)))
use_clipped_redraw = TRUE;
@@ -1039,9 +827,6 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
else
paint_stage (stage_cogl, view, &view_rect);
}
maybe_paint_frame_times (stage_window, view);
cogl_pop_framebuffer ();
if (may_use_clipped_redraw &&
@@ -1146,8 +931,6 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
gboolean swap_event = FALSE;
GList *l;
append_frame_time_info (stage_cogl);
for (l = _clutter_stage_window_get_views (stage_window); l; l = l->next)
{
ClutterStageView *view = l->data;

View File

@@ -66,9 +66,6 @@ struct _ClutterStageCogl
/* TRUE if the current paint cycle has a clipped redraw. In that
case bounding_redraw_clip specifies the the bounds. */
guint using_clipped_redraw : 1;
gboolean painting_frame_chart;
GArray *frame_times;
};
struct _ClutterStageCoglClass

View File

@@ -77,6 +77,9 @@ gulong clutter_get_timestamp (void);
CLUTTER_DEPRECATED
gboolean clutter_get_debug_enabled (void);
CLUTTER_DEPRECATED
gboolean clutter_get_show_fps (void);
G_END_DECLS
#endif /* __CLUTTER_MAIN_DEPRECATED_H__ */

View File

@@ -1132,13 +1132,13 @@ clutter_input_device_evdev_process_kbd_a11y_event (ClutterEvent *e
if (event->key.flags & CLUTTER_EVENT_FLAG_INPUT_METHOD)
goto emit_event;
if (device_evdev->a11y_flags & CLUTTER_A11Y_KEYBOARD_ENABLED)
{
if (event->type == CLUTTER_KEY_PRESS)
handle_enablekeys_press (event, device_evdev);
else
handle_enablekeys_release (event, device_evdev);
}
if (!(device_evdev->a11y_flags & CLUTTER_A11Y_KEYBOARD_ENABLED))
goto emit_event;
if (event->type == CLUTTER_KEY_PRESS)
handle_enablekeys_press (event, device_evdev);
else
handle_enablekeys_release (event, device_evdev);
if (device_evdev->a11y_flags & CLUTTER_A11Y_MOUSE_KEYS_ENABLED)
{

View File

@@ -103,6 +103,9 @@ struct _CoglContext
unsigned long private_features
[COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_N_PRIVATE_FEATURES)];
gboolean needs_viewport_scissor_workaround;
CoglFramebuffer *viewport_scissor_workaround_framebuffer;
CoglPipeline *default_pipeline;
CoglPipelineLayer *default_layer_0;
CoglPipelineLayer *default_layer_n;
@@ -266,6 +269,7 @@ struct _CoglContext
GLuint current_gl_program;
gboolean current_gl_dither_enabled;
CoglColorMask current_gl_color_mask;
GLenum current_gl_draw_buffer;
/* Clipping */

View File

@@ -265,6 +265,22 @@ cogl_context_new (CoglDisplay *display,
/* Initialise the driver specific state */
_cogl_init_feature_overrides (context);
/* XXX: ONGOING BUG: Intel viewport scissor
*
* Intel gen6 drivers don't currently correctly handle offset
* viewports, since primitives aren't clipped within the bounds of
* the viewport. To workaround this we push our own clip for the
* viewport that will use scissoring to ensure we clip as expected.
*
* TODO: file a bug upstream!
*/
if (context->gpu.driver_package == COGL_GPU_INFO_DRIVER_PACKAGE_MESA &&
context->gpu.architecture == COGL_GPU_INFO_ARCHITECTURE_SANDYBRIDGE &&
!getenv ("COGL_DISABLE_INTEL_VIEWPORT_SCISSORT_WORKAROUND"))
context->needs_viewport_scissor_workaround = TRUE;
else
context->needs_viewport_scissor_workaround = FALSE;
context->sampler_cache = _cogl_sampler_cache_new (context);
_cogl_pipeline_init_default_pipeline ();
@@ -350,6 +366,7 @@ cogl_context_new (CoglDisplay *display,
context->current_gl_program = 0;
context->current_gl_dither_enabled = TRUE;
context->current_gl_color_mask = COGL_COLOR_MASK_ALL;
context->gl_blend_enable_cache = FALSE;

View File

@@ -83,10 +83,11 @@ typedef enum _CoglFramebufferStateIndex
COGL_FRAMEBUFFER_STATE_INDEX_DITHER = 3,
COGL_FRAMEBUFFER_STATE_INDEX_MODELVIEW = 4,
COGL_FRAMEBUFFER_STATE_INDEX_PROJECTION = 5,
COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING = 6,
COGL_FRAMEBUFFER_STATE_INDEX_DEPTH_WRITE = 7,
COGL_FRAMEBUFFER_STATE_INDEX_STEREO_MODE = 8,
COGL_FRAMEBUFFER_STATE_INDEX_MAX = 9
COGL_FRAMEBUFFER_STATE_INDEX_COLOR_MASK = 6,
COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING = 7,
COGL_FRAMEBUFFER_STATE_INDEX_DEPTH_WRITE = 8,
COGL_FRAMEBUFFER_STATE_INDEX_STEREO_MODE = 9,
COGL_FRAMEBUFFER_STATE_INDEX_MAX = 10
} CoglFramebufferStateIndex;
typedef enum _CoglFramebufferState
@@ -97,9 +98,10 @@ typedef enum _CoglFramebufferState
COGL_FRAMEBUFFER_STATE_DITHER = 1<<3,
COGL_FRAMEBUFFER_STATE_MODELVIEW = 1<<4,
COGL_FRAMEBUFFER_STATE_PROJECTION = 1<<5,
COGL_FRAMEBUFFER_STATE_FRONT_FACE_WINDING = 1<<6,
COGL_FRAMEBUFFER_STATE_DEPTH_WRITE = 1<<7,
COGL_FRAMEBUFFER_STATE_STEREO_MODE = 1<<8
COGL_FRAMEBUFFER_STATE_COLOR_MASK = 1<<6,
COGL_FRAMEBUFFER_STATE_FRONT_FACE_WINDING = 1<<7,
COGL_FRAMEBUFFER_STATE_DEPTH_WRITE = 1<<8,
COGL_FRAMEBUFFER_STATE_STEREO_MODE = 1<<9
} CoglFramebufferState;
#define COGL_FRAMEBUFFER_STATE_ALL ((1<<COGL_FRAMEBUFFER_STATE_INDEX_MAX) - 1)
@@ -153,6 +155,7 @@ struct _CoglFramebuffer
gboolean dither_enabled;
gboolean depth_writing_enabled;
CoglColorMask color_mask;
CoglStereoMode stereo_mode;
/* We journal the textured rectangles we want to submit to OpenGL so

View File

@@ -123,6 +123,8 @@ _cogl_framebuffer_init (CoglFramebuffer *framebuffer,
framebuffer->dirty_bitmasks = TRUE;
framebuffer->color_mask = COGL_COLOR_MASK_ALL;
framebuffer->samples_per_pixel = 0;
framebuffer->clip_stack = NULL;
@@ -189,6 +191,9 @@ _cogl_framebuffer_free (CoglFramebuffer *framebuffer)
cogl_object_unref (framebuffer->journal);
if (ctx->viewport_scissor_workaround_framebuffer == framebuffer)
ctx->viewport_scissor_workaround_framebuffer = NULL;
ctx->framebuffers = g_list_remove (ctx->framebuffers, framebuffer);
if (ctx->current_draw_buffer == framebuffer)
@@ -255,11 +260,13 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer,
float blue,
float alpha)
{
CoglContext *ctx = framebuffer->context;
CoglClipStack *clip_stack = _cogl_framebuffer_get_clip_stack (framebuffer);
int scissor_x0;
int scissor_y0;
int scissor_x1;
int scissor_y1;
gboolean saved_viewport_scissor_workaround;
if (!framebuffer->depth_buffer_clear_needed &&
(buffers & COGL_BUFFER_BIT_DEPTH))
@@ -354,6 +361,31 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer,
_cogl_framebuffer_flush_journal (framebuffer);
/* XXX: ONGOING BUG: Intel viewport scissor
*
* The semantics of cogl_framebuffer_clear() are that it should not
* be affected by the current viewport and so if we are currently
* applying a workaround for viewport scissoring we need to
* temporarily disable the workaround before clearing so any
* special scissoring for the workaround will be removed first.
*
* Note: we only need to disable the workaround if the current
* viewport doesn't match the framebuffer's size since otherwise
* the workaround wont affect clearing anyway.
*/
if (ctx->needs_viewport_scissor_workaround &&
(framebuffer->viewport_x != 0 ||
framebuffer->viewport_y != 0 ||
framebuffer->viewport_width != framebuffer->width ||
framebuffer->viewport_height != framebuffer->height))
{
saved_viewport_scissor_workaround = TRUE;
ctx->needs_viewport_scissor_workaround = FALSE;
ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_CLIP;
}
else
saved_viewport_scissor_workaround = FALSE;
/* NB: _cogl_framebuffer_flush_state may disrupt various state (such
* as the pipeline state) when flushing the clip stack, so should
* always be done first when preparing to draw. */
@@ -363,6 +395,16 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer,
_cogl_framebuffer_clear_without_flush4f (framebuffer, buffers,
red, green, blue, alpha);
/* XXX: ONGOING BUG: Intel viewport scissor
*
* See comment about temporarily disabling this workaround above
*/
if (saved_viewport_scissor_workaround)
{
ctx->needs_viewport_scissor_workaround = TRUE;
ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_CLIP;
}
/* This is a debugging variable used to visually display the quad
* batches from the journal. It is reset here to increase the
* chances of getting the same colours for each frame during an
@@ -510,7 +552,12 @@ cogl_framebuffer_set_viewport (CoglFramebuffer *framebuffer,
framebuffer->viewport_age++;
if (context->current_draw_buffer == framebuffer)
context->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_VIEWPORT;
{
context->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_VIEWPORT;
if (context->needs_viewport_scissor_workaround)
context->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_CLIP;
}
}
float
@@ -784,7 +831,27 @@ _cogl_framebuffer_compare_viewport_state (CoglFramebuffer *a,
/* NB: we render upside down to offscreen framebuffers and that
* can affect how we setup the GL viewport... */
a->type != b->type)
return COGL_FRAMEBUFFER_STATE_VIEWPORT;
{
unsigned long differences = COGL_FRAMEBUFFER_STATE_VIEWPORT;
CoglContext *context = a->context;
/* XXX: ONGOING BUG: Intel viewport scissor
*
* Intel gen6 drivers don't currently correctly handle offset
* viewports, since primitives aren't clipped within the bounds of
* the viewport. To workaround this we push our own clip for the
* viewport that will use scissoring to ensure we clip as expected.
*
* This workaround implies that a change in viewport state is
* effectively also a change in the clipping state.
*
* TODO: file a bug upstream!
*/
if (G_UNLIKELY (context->needs_viewport_scissor_workaround))
differences |= COGL_FRAMEBUFFER_STATE_CLIP;
return differences;
}
else
return 0;
}
@@ -827,6 +894,17 @@ _cogl_framebuffer_compare_projection_state (CoglFramebuffer *a,
return COGL_FRAMEBUFFER_STATE_PROJECTION;
}
static unsigned long
_cogl_framebuffer_compare_color_mask_state (CoglFramebuffer *a,
CoglFramebuffer *b)
{
if (cogl_framebuffer_get_color_mask (a) !=
cogl_framebuffer_get_color_mask (b))
return COGL_FRAMEBUFFER_STATE_COLOR_MASK;
else
return 0;
}
static unsigned long
_cogl_framebuffer_compare_front_face_winding_state (CoglFramebuffer *a,
CoglFramebuffer *b)
@@ -893,6 +971,10 @@ _cogl_framebuffer_compare (CoglFramebuffer *a,
differences |=
_cogl_framebuffer_compare_projection_state (a, b);
break;
case COGL_FRAMEBUFFER_STATE_INDEX_COLOR_MASK:
differences |=
_cogl_framebuffer_compare_color_mask_state (a, b);
break;
case COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING:
differences |=
_cogl_framebuffer_compare_front_face_winding_state (a, b);
@@ -998,6 +1080,29 @@ cogl_framebuffer_get_is_stereo (CoglFramebuffer *framebuffer)
return framebuffer->config.stereo_enabled;
}
CoglColorMask
cogl_framebuffer_get_color_mask (CoglFramebuffer *framebuffer)
{
return framebuffer->color_mask;
}
void
cogl_framebuffer_set_color_mask (CoglFramebuffer *framebuffer,
CoglColorMask color_mask)
{
if (framebuffer->color_mask == color_mask)
return;
/* XXX: Currently color mask changes don't go through the journal */
_cogl_framebuffer_flush_journal (framebuffer);
framebuffer->color_mask = color_mask;
if (framebuffer->context->current_draw_buffer == framebuffer)
framebuffer->context->current_draw_buffer_changes |=
COGL_FRAMEBUFFER_STATE_COLOR_MASK;
}
CoglStereoMode
cogl_framebuffer_get_stereo_mode (CoglFramebuffer *framebuffer)
{

View File

@@ -816,6 +816,38 @@ void
cogl_framebuffer_set_depth_write_enabled (CoglFramebuffer *framebuffer,
gboolean depth_write_enabled);
/**
* cogl_framebuffer_get_color_mask:
* @framebuffer: a pointer to a #CoglFramebuffer
*
* Gets the current #CoglColorMask of which channels would be written to the
* current framebuffer. Each bit set in the mask means that the
* corresponding color would be written.
*
* Returns: A #CoglColorMask
* Since: 1.8
* Stability: unstable
*/
CoglColorMask
cogl_framebuffer_get_color_mask (CoglFramebuffer *framebuffer);
/**
* cogl_framebuffer_set_color_mask:
* @framebuffer: a pointer to a #CoglFramebuffer
* @color_mask: A #CoglColorMask of which color channels to write to
* the current framebuffer.
*
* Defines a bit mask of which color channels should be written to the
* given @framebuffer. If a bit is set in @color_mask that means that
* color will be written.
*
* Since: 1.8
* Stability: unstable
*/
void
cogl_framebuffer_set_color_mask (CoglFramebuffer *framebuffer,
CoglColorMask color_mask);
/**
* cogl_framebuffer_get_stereo_mode:
* @framebuffer: a pointer to a #CoglFramebuffer

View File

@@ -87,6 +87,7 @@ typedef enum
COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE_INDEX,
COGL_PIPELINE_STATE_POINT_SIZE_INDEX,
COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE_INDEX,
COGL_PIPELINE_STATE_LOGIC_OPS_INDEX,
COGL_PIPELINE_STATE_CULL_FACE_INDEX,
COGL_PIPELINE_STATE_UNIFORMS_INDEX,
COGL_PIPELINE_STATE_VERTEX_SNIPPETS_INDEX,
@@ -139,6 +140,8 @@ typedef enum _CoglPipelineState
1L<<COGL_PIPELINE_STATE_POINT_SIZE_INDEX,
COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE =
1L<<COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE_INDEX,
COGL_PIPELINE_STATE_LOGIC_OPS =
1L<<COGL_PIPELINE_STATE_LOGIC_OPS_INDEX,
COGL_PIPELINE_STATE_CULL_FACE =
1L<<COGL_PIPELINE_STATE_CULL_FACE_INDEX,
COGL_PIPELINE_STATE_UNIFORMS =
@@ -185,6 +188,7 @@ typedef enum _CoglPipelineState
COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE | \
COGL_PIPELINE_STATE_POINT_SIZE | \
COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE | \
COGL_PIPELINE_STATE_LOGIC_OPS | \
COGL_PIPELINE_STATE_CULL_FACE | \
COGL_PIPELINE_STATE_UNIFORMS | \
COGL_PIPELINE_STATE_VERTEX_SNIPPETS | \
@@ -196,6 +200,7 @@ typedef enum _CoglPipelineState
COGL_PIPELINE_STATE_BLEND | \
COGL_PIPELINE_STATE_DEPTH | \
COGL_PIPELINE_STATE_FOG | \
COGL_PIPELINE_STATE_LOGIC_OPS | \
COGL_PIPELINE_STATE_CULL_FACE | \
COGL_PIPELINE_STATE_UNIFORMS | \
COGL_PIPELINE_STATE_VERTEX_SNIPPETS | \
@@ -260,6 +265,11 @@ typedef struct
float z_far;
} CoglPipelineFogState;
typedef struct
{
CoglColorMask color_mask;
} CoglPipelineLogicOpsState;
typedef struct
{
CoglPipelineCullFaceMode mode;
@@ -291,6 +301,7 @@ typedef struct
float point_size;
unsigned int non_zero_point_size : 1;
unsigned int per_vertex_point_size : 1;
CoglPipelineLogicOpsState logic_ops_state;
CoglPipelineCullFaceState cull_face_state;
CoglPipelineUniformsState uniforms_state;
CoglPipelineSnippetList vertex_snippets;

View File

@@ -218,6 +218,16 @@ _cogl_pipeline_per_vertex_point_size_equal (CoglPipeline *authority0,
authority1->big_state->per_vertex_point_size);
}
gboolean
_cogl_pipeline_logic_ops_state_equal (CoglPipeline *authority0,
CoglPipeline *authority1)
{
CoglPipelineLogicOpsState *logic_ops_state0 = &authority0->big_state->logic_ops_state;
CoglPipelineLogicOpsState *logic_ops_state1 = &authority1->big_state->logic_ops_state;
return logic_ops_state0->color_mask == logic_ops_state1->color_mask;
}
gboolean
_cogl_pipeline_cull_face_state_equal (CoglPipeline *authority0,
CoglPipeline *authority1)
@@ -1193,6 +1203,49 @@ cogl_pipeline_get_depth_state (CoglPipeline *pipeline,
*state = authority->big_state->depth_state;
}
CoglColorMask
cogl_pipeline_get_color_mask (CoglPipeline *pipeline)
{
CoglPipeline *authority;
_COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), 0);
authority =
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LOGIC_OPS);
return authority->big_state->logic_ops_state.color_mask;
}
void
cogl_pipeline_set_color_mask (CoglPipeline *pipeline,
CoglColorMask color_mask)
{
CoglPipelineState state = COGL_PIPELINE_STATE_LOGIC_OPS;
CoglPipeline *authority;
CoglPipelineLogicOpsState *logic_ops_state;
_COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));
authority = _cogl_pipeline_get_authority (pipeline, state);
logic_ops_state = &authority->big_state->logic_ops_state;
if (logic_ops_state->color_mask == color_mask)
return;
/* - Flush journal primitives referencing the current state.
* - Make sure the pipeline has no dependants so it may be modified.
* - If the pipeline isn't currently an authority for the state being
* changed, then initialize that state from the current authority.
*/
_cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE);
logic_ops_state = &pipeline->big_state->logic_ops_state;
logic_ops_state->color_mask = color_mask;
_cogl_pipeline_update_authority (pipeline, authority, state,
_cogl_pipeline_logic_ops_state_equal);
}
void
_cogl_pipeline_set_fog_state (CoglPipeline *pipeline,
const CoglPipelineFogState *fog_state)
@@ -1898,6 +1951,15 @@ _cogl_pipeline_hash_per_vertex_point_size_state (CoglPipeline *authority,
sizeof (per_vertex_point_size));
}
void
_cogl_pipeline_hash_logic_ops_state (CoglPipeline *authority,
CoglPipelineHashState *state)
{
CoglPipelineLogicOpsState *logic_ops_state = &authority->big_state->logic_ops_state;
state->hash = _cogl_util_one_at_a_time_hash (state->hash, &logic_ops_state->color_mask,
sizeof (CoglColorMask));
}
void
_cogl_pipeline_hash_cull_face_state (CoglPipeline *authority,
CoglPipelineHashState *state)

View File

@@ -571,6 +571,38 @@ cogl_pipeline_set_per_vertex_point_size (CoglPipeline *pipeline,
gboolean
cogl_pipeline_get_per_vertex_point_size (CoglPipeline *pipeline);
/**
* cogl_pipeline_get_color_mask:
* @pipeline: a #CoglPipeline object.
*
* Gets the current #CoglColorMask of which channels would be written to the
* current framebuffer. Each bit set in the mask means that the
* corresponding color would be written.
*
* Returns: A #CoglColorMask
* Since: 1.8
* Stability: unstable
*/
CoglColorMask
cogl_pipeline_get_color_mask (CoglPipeline *pipeline);
/**
* cogl_pipeline_set_color_mask:
* @pipeline: a #CoglPipeline object.
* @color_mask: A #CoglColorMask of which color channels to write to
* the current framebuffer.
*
* Defines a bit mask of which color channels should be written to the
* current framebuffer. If a bit is set in @color_mask that means that
* color will be written.
*
* Since: 1.8
* Stability: unstable
*/
void
cogl_pipeline_set_color_mask (CoglPipeline *pipeline,
CoglColorMask color_mask);
/**
* cogl_pipeline_get_user_program:
* @pipeline: a #CoglPipeline object.

View File

@@ -99,6 +99,7 @@ _cogl_pipeline_init_default_pipeline (void)
CoglPipelineLightingState *lighting_state = &big_state->lighting_state;
CoglPipelineAlphaFuncState *alpha_state = &big_state->alpha_state;
CoglPipelineBlendState *blend_state = &big_state->blend_state;
CoglPipelineLogicOpsState *logic_ops_state = &big_state->logic_ops_state;
CoglPipelineCullFaceState *cull_face_state = &big_state->cull_face_state;
CoglPipelineUniformsState *uniforms_state = &big_state->uniforms_state;
@@ -188,6 +189,8 @@ _cogl_pipeline_init_default_pipeline (void)
big_state->point_size = 0.0f;
logic_ops_state->color_mask = COGL_COLOR_MASK_ALL;
cull_face_state->mode = COGL_PIPELINE_CULL_FACE_MODE_NONE;
cull_face_state->front_winding = COGL_WINDING_COUNTER_CLOCKWISE;
@@ -1027,6 +1030,13 @@ _cogl_pipeline_copy_differences (CoglPipeline *dest,
if (differences & COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE)
big_state->per_vertex_point_size = src->big_state->per_vertex_point_size;
if (differences & COGL_PIPELINE_STATE_LOGIC_OPS)
{
memcpy (&big_state->logic_ops_state,
&src->big_state->logic_ops_state,
sizeof (CoglPipelineLogicOpsState));
}
if (differences & COGL_PIPELINE_STATE_CULL_FACE)
{
memcpy (&big_state->cull_face_state,
@@ -1140,6 +1150,13 @@ _cogl_pipeline_init_multi_property_sparse_state (CoglPipeline *pipeline,
sizeof (CoglPipelineFogState));
break;
}
case COGL_PIPELINE_STATE_LOGIC_OPS:
{
memcpy (&pipeline->big_state->logic_ops_state,
&authority->big_state->logic_ops_state,
sizeof (CoglPipelineLogicOpsState));
break;
}
case COGL_PIPELINE_STATE_CULL_FACE:
{
memcpy (&pipeline->big_state->cull_face_state,
@@ -2306,6 +2323,11 @@ _cogl_pipeline_equal (CoglPipeline *pipeline0,
authorities1[bit]))
goto done;
break;
case COGL_PIPELINE_STATE_LOGIC_OPS_INDEX:
if (!_cogl_pipeline_logic_ops_state_equal (authorities0[bit],
authorities1[bit]))
goto done;
break;
case COGL_PIPELINE_STATE_USER_SHADER_INDEX:
if (!_cogl_pipeline_user_shader_equal (authorities0[bit],
authorities1[bit]))
@@ -2754,6 +2776,8 @@ _cogl_pipeline_init_state_hash_functions (void)
_cogl_pipeline_hash_point_size_state;
state_hash_functions[COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE_INDEX] =
_cogl_pipeline_hash_per_vertex_point_size_state;
state_hash_functions[COGL_PIPELINE_STATE_LOGIC_OPS_INDEX] =
_cogl_pipeline_hash_logic_ops_state;
state_hash_functions[COGL_PIPELINE_STATE_UNIFORMS_INDEX] =
_cogl_pipeline_hash_uniforms_state;
state_hash_functions[COGL_PIPELINE_STATE_VERTEX_SNIPPETS_INDEX] =
@@ -2763,7 +2787,7 @@ _cogl_pipeline_init_state_hash_functions (void)
{
/* So we get a big error if we forget to update this code! */
_COGL_STATIC_ASSERT (COGL_PIPELINE_STATE_SPARSE_COUNT == 17,
_COGL_STATIC_ASSERT (COGL_PIPELINE_STATE_SPARSE_COUNT == 18,
"Make sure to install a hash function for "
"newly added pipeline state and update assert "
"in _cogl_pipeline_init_state_hash_functions");

View File

@@ -55,6 +55,11 @@ G_BEGIN_DECLS
* made up of multiple 2D textures, or atlas textures where Cogl must
* internally modify user texture coordinates before they can be used
* by the GPU.
*
* You should be aware that many GPUs only support power of two sizes
* for #CoglTexture2D textures. You can check support for non power of
* two textures by checking for the %COGL_FEATURE_ID_TEXTURE_NPOT feature
* via cogl_has_feature().
*/
typedef struct _CoglTexture2D CoglTexture2D;
@@ -100,6 +105,11 @@ cogl_is_texture_2d (void *object);
* using cogl_texture_set_components() and
* cogl_texture_set_premultiplied().
*
* <note>Many GPUs only support power of two sizes for #CoglTexture2D
* textures. You can check support for non power of two textures by
* checking for the %COGL_FEATURE_ID_TEXTURE_NPOT feature via
* cogl_has_feature().</note>
*
* Returns: (transfer full): A new #CoglTexture2D object with no storage yet allocated.
*
* Since: 2.0
@@ -128,6 +138,11 @@ cogl_texture_2d_new_with_size (CoglContext *ctx,
* using cogl_texture_set_components() and
* cogl_texture_set_premultiplied().
*
* <note>Many GPUs only support power of two sizes for #CoglTexture2D
* textures. You can check support for non power of two textures by
* checking for the %COGL_FEATURE_ID_TEXTURE_NPOT feature via
* cogl_has_feature().</note>
*
* Return value: (transfer full): A newly created #CoglTexture2D or %NULL on failure
* and @error will be updated.
*
@@ -164,6 +179,11 @@ cogl_texture_2d_new_from_file (CoglContext *ctx,
* cogl_texture_2d_new_with_size() and then upload data using
* cogl_texture_set_data()</note>
*
* <note>Many GPUs only support power of two sizes for #CoglTexture2D
* textures. You can check support for non power of two textures by
* checking for the %COGL_FEATURE_ID_TEXTURE_NPOT feature via
* cogl_has_feature().</note>
*
* Returns: (transfer full): A newly allocated #CoglTexture2D, or if
* the size is not supported (because it is too large or a
* non-power-of-two size that the hardware doesn't support)
@@ -198,6 +218,11 @@ cogl_texture_2d_new_from_data (CoglContext *ctx,
* using cogl_texture_set_components() and
* cogl_texture_set_premultiplied().
*
* <note>Many GPUs only support power of two sizes for #CoglTexture2D
* textures. You can check support for non power of two textures by
* checking for the %COGL_FEATURE_ID_TEXTURE_NPOT feature via
* cogl_has_feature().</note>
*
* Returns: (transfer full): A newly allocated #CoglTexture2D
*
* Since: 2.0

View File

@@ -773,6 +773,32 @@ typedef enum _CoglWinsysFeature
COGL_WINSYS_FEATURE_N_FEATURES
} CoglWinsysFeature;
/**
* CoglColorMask:
* @COGL_COLOR_MASK_NONE: None of the color channels are masked
* @COGL_COLOR_MASK_RED: Masks the red color channel
* @COGL_COLOR_MASK_GREEN: Masks the green color channel
* @COGL_COLOR_MASK_BLUE: Masks the blue color channel
* @COGL_COLOR_MASK_ALPHA: Masks the alpha color channel
* @COGL_COLOR_MASK_ALL: All of the color channels are masked
*
* Defines a bit mask of color channels. This can be used with
* cogl_pipeline_set_color_mask() for example to define which color
* channels should be written to the current framebuffer when
* drawing something.
*/
typedef enum
{
COGL_COLOR_MASK_NONE = 0,
COGL_COLOR_MASK_RED = 1L<<0,
COGL_COLOR_MASK_GREEN = 1L<<1,
COGL_COLOR_MASK_BLUE = 1L<<2,
COGL_COLOR_MASK_ALPHA = 1L<<3,
/* XXX: glib-mkenums is a perl script that can't cope if we split
* this onto multiple lines! *sigh* */
COGL_COLOR_MASK_ALL = (COGL_COLOR_MASK_RED | COGL_COLOR_MASK_GREEN | COGL_COLOR_MASK_BLUE | COGL_COLOR_MASK_ALPHA)
} CoglColorMask;
/**
* CoglWinding:
* @COGL_WINDING_CLOCKWISE: Vertices are in a clockwise order

View File

@@ -132,6 +132,7 @@ cogl_color_init_from_hsl
cogl_color_init_from_4f
cogl_color_init_from_4fv
cogl_color_init_from_4ub
cogl_color_mask_get_type
cogl_color_new
cogl_color_premultiply
cogl_color_set_alpha
@@ -253,6 +254,7 @@ cogl_framebuffer_frustum
cogl_framebuffer_get_alpha_bits
cogl_framebuffer_get_blue_bits
cogl_framebuffer_get_color_format
cogl_framebuffer_get_color_mask
cogl_framebuffer_get_context
cogl_framebuffer_get_depth_bits
cogl_framebuffer_get_depth_texture
@@ -295,6 +297,7 @@ cogl_framebuffer_rotate_quaternion
#endif
cogl_framebuffer_scale
cogl_framebuffer_set_color_mask
cogl_framebuffer_set_depth_texture_enabled
cogl_framebuffer_set_depth_write_enabled
cogl_framebuffer_set_dither_enabled
@@ -617,6 +620,7 @@ cogl_pipeline_get_alpha_test_function
cogl_pipeline_get_alpha_test_reference
cogl_pipeline_get_ambient
cogl_pipeline_get_color
cogl_pipeline_get_color_mask
cogl_pipeline_get_cull_face_mode
cogl_pipeline_get_depth_state
cogl_pipeline_get_diffuse
@@ -646,6 +650,7 @@ cogl_pipeline_set_ambient_and_diffuse
cogl_pipeline_set_blend
cogl_pipeline_set_blend_constant
cogl_pipeline_set_color
cogl_pipeline_set_color_mask
cogl_pipeline_set_color4f
cogl_pipeline_set_color4ub
cogl_pipeline_set_cull_face_mode

View File

@@ -435,7 +435,12 @@ _cogl_clip_stack_gl_flush (CoglClipStack *stack,
anything */
if (ctx->current_clip_stack_valid)
{
if (ctx->current_clip_stack == stack)
if (ctx->current_clip_stack == stack &&
(ctx->needs_viewport_scissor_workaround == FALSE ||
(framebuffer->viewport_age ==
framebuffer->viewport_age_for_scissor_workaround &&
ctx->viewport_scissor_workaround_framebuffer ==
framebuffer)))
return;
_cogl_clip_stack_unref (ctx->current_clip_stack);
@@ -452,8 +457,10 @@ _cogl_clip_stack_gl_flush (CoglClipStack *stack,
GE( ctx, glDisable (GL_STENCIL_TEST) );
/* If the stack is empty then there's nothing else to do
*
* See comment below about ctx->needs_viewport_scissor_workaround
*/
if (stack == NULL)
if (stack == NULL && !ctx->needs_viewport_scissor_workaround)
{
COGL_NOTE (CLIPPING, "Flushed empty clip stack");
@@ -470,6 +477,31 @@ _cogl_clip_stack_gl_flush (CoglClipStack *stack,
&scissor_x0, &scissor_y0,
&scissor_x1, &scissor_y1);
/* XXX: ONGOING BUG: Intel viewport scissor
*
* Intel gen6 drivers don't correctly handle offset viewports, since
* primitives aren't clipped within the bounds of the viewport. To
* workaround this we push our own clip for the viewport that will
* use scissoring to ensure we clip as expected.
*
* TODO: file a bug upstream!
*/
if (ctx->needs_viewport_scissor_workaround)
{
_cogl_util_scissor_intersect (framebuffer->viewport_x,
framebuffer->viewport_y,
framebuffer->viewport_x +
framebuffer->viewport_width,
framebuffer->viewport_y +
framebuffer->viewport_height,
&scissor_x0, &scissor_y0,
&scissor_x1, &scissor_y1);
framebuffer->viewport_age_for_scissor_workaround =
framebuffer->viewport_age;
ctx->viewport_scissor_workaround_framebuffer =
framebuffer;
}
/* Enable scissoring as soon as possible */
if (scissor_x0 >= scissor_x1 || scissor_y0 >= scissor_y1)
scissor_x0 = scissor_y0 = scissor_x1 = scissor_y1 = scissor_y_start = 0;

View File

@@ -195,6 +195,20 @@ _cogl_framebuffer_gl_flush_projection_state (CoglFramebuffer *framebuffer)
projection_entry);
}
static void
_cogl_framebuffer_gl_flush_color_mask_state (CoglFramebuffer *framebuffer)
{
CoglContext *context = framebuffer->context;
/* The color mask state is really owned by a CoglPipeline so to
* ensure the color mask is updated the next time we draw something
* we need to make sure the logic ops for the pipeline are
* re-flushed... */
context->current_pipeline_changes_since_flush |=
COGL_PIPELINE_STATE_LOGIC_OPS;
context->current_pipeline_age--;
}
static void
_cogl_framebuffer_gl_flush_front_face_winding_state (CoglFramebuffer *framebuffer)
{
@@ -423,6 +437,9 @@ _cogl_framebuffer_gl_flush_state (CoglFramebuffer *draw_buffer,
case COGL_FRAMEBUFFER_STATE_INDEX_PROJECTION:
_cogl_framebuffer_gl_flush_projection_state (draw_buffer);
break;
case COGL_FRAMEBUFFER_STATE_INDEX_COLOR_MASK:
_cogl_framebuffer_gl_flush_color_mask_state (draw_buffer);
break;
case COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING:
_cogl_framebuffer_gl_flush_front_face_winding_state (draw_buffer);
break;
@@ -951,6 +968,20 @@ _cogl_framebuffer_gl_clear (CoglFramebuffer *framebuffer,
{
GE( ctx, glClearColor (red, green, blue, alpha) );
gl_buffers |= GL_COLOR_BUFFER_BIT;
if (ctx->current_gl_color_mask != framebuffer->color_mask)
{
CoglColorMask color_mask = framebuffer->color_mask;
GE( ctx, glColorMask (!!(color_mask & COGL_COLOR_MASK_RED),
!!(color_mask & COGL_COLOR_MASK_GREEN),
!!(color_mask & COGL_COLOR_MASK_BLUE),
!!(color_mask & COGL_COLOR_MASK_ALPHA)));
ctx->current_gl_color_mask = color_mask;
/* Make sure the ColorMask is updated when the next primitive is drawn */
ctx->current_pipeline_changes_since_flush |=
COGL_PIPELINE_STATE_LOGIC_OPS;
ctx->current_pipeline_age--;
}
}
if (buffers & COGL_BUFFER_BIT_DEPTH)

View File

@@ -581,6 +581,23 @@ _cogl_pipeline_flush_color_blend_alpha_depth_state (
flush_depth_state (ctx, depth_state);
}
if (pipelines_difference & COGL_PIPELINE_STATE_LOGIC_OPS)
{
CoglPipeline *authority =
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LOGIC_OPS);
CoglPipelineLogicOpsState *logic_ops_state = &authority->big_state->logic_ops_state;
CoglColorMask color_mask = logic_ops_state->color_mask;
if (ctx->current_draw_buffer)
color_mask &= ctx->current_draw_buffer->color_mask;
GE (ctx, glColorMask (!!(color_mask & COGL_COLOR_MASK_RED),
!!(color_mask & COGL_COLOR_MASK_GREEN),
!!(color_mask & COGL_COLOR_MASK_BLUE),
!!(color_mask & COGL_COLOR_MASK_ALPHA)));
ctx->current_gl_color_mask = color_mask;
}
if (pipelines_difference & COGL_PIPELINE_STATE_CULL_FACE)
{
CoglPipeline *authority =

View File

@@ -317,13 +317,31 @@ check_gl_version (CoglContext *ctx,
return FALSE;
}
/* We require GLSL 1.20, which is implied by OpenGL 2.1. */
if (!COGL_CHECK_GL_VERSION (major, minor, 2, 1))
/* GL 1.3 supports all of the required functionality in core */
if (COGL_CHECK_GL_VERSION (major, minor, 1, 3))
return TRUE;
/* OpenGL 1.2 is only supported if we have the multitexturing
extension */
if (!_cogl_check_extension ("GL_ARB_multitexture", gl_extensions))
{
_cogl_set_error (error,
COGL_DRIVER_ERROR,
COGL_DRIVER_ERROR_INVALID_VERSION,
"OpenGL 2.1 or better is required");
COGL_DRIVER_ERROR,
COGL_DRIVER_ERROR_INVALID_VERSION,
"The OpenGL driver is missing "
"the GL_ARB_multitexture extension");
return FALSE;
}
/* OpenGL 1.2 is required */
if (!COGL_CHECK_GL_VERSION (major, minor, 1, 2))
{
_cogl_set_error (error,
COGL_DRIVER_ERROR,
COGL_DRIVER_ERROR_INVALID_VERSION,
"The OpenGL version of your driver (%i.%i) "
"is not compatible with Cogl",
major, minor);
return FALSE;
}
@@ -338,7 +356,6 @@ _cogl_driver_update_features (CoglContext *ctx,
unsigned long private_features
[COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_N_PRIVATE_FEATURES)] = { 0 };
char **gl_extensions;
const char *glsl_version;
int gl_major = 0, gl_minor = 0;
int i;
@@ -386,13 +403,23 @@ _cogl_driver_update_features (CoglContext *ctx,
_cogl_gpu_info_init (ctx, &ctx->gpu);
ctx->glsl_major = 1;
ctx->glsl_minor = 2;
ctx->glsl_version_to_use = 120;
ctx->glsl_minor = 1;
glsl_version = (char *)ctx->glGetString (GL_SHADING_LANGUAGE_VERSION);
_cogl_gl_util_parse_gl_version (glsl_version,
&ctx->glsl_major,
&ctx->glsl_minor);
if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0))
{
const char *glsl_version =
(char *)ctx->glGetString (GL_SHADING_LANGUAGE_VERSION);
_cogl_gl_util_parse_gl_version (glsl_version,
&ctx->glsl_major,
&ctx->glsl_minor);
}
if (COGL_CHECK_GL_VERSION (ctx->glsl_major, ctx->glsl_minor, 1, 2))
/* We want to use version 120 if it is available so that the
* gl_PointCoord can be used. */
ctx->glsl_version_to_use = 120;
else
ctx->glsl_version_to_use = 110;
flags = (COGL_FEATURE_TEXTURE_READ_PIXELS
| COGL_FEATURE_UNSIGNED_INT_INDICES
@@ -400,21 +427,30 @@ _cogl_driver_update_features (CoglContext *ctx,
COGL_FLAGS_SET (ctx->features,
COGL_FEATURE_ID_UNSIGNED_INT_INDICES, TRUE);
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_DEPTH_RANGE, TRUE);
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_MIRRORED_REPEAT, TRUE);
if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 1, 4))
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_MIRRORED_REPEAT, TRUE);
_cogl_feature_check_ext_functions (ctx,
gl_major,
gl_minor,
gl_extensions);
flags |= COGL_FEATURE_TEXTURE_NPOT
| COGL_FEATURE_TEXTURE_NPOT_BASIC
| COGL_FEATURE_TEXTURE_NPOT_MIPMAP
| COGL_FEATURE_TEXTURE_NPOT_REPEAT;
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_TEXTURE_NPOT, TRUE);
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_TEXTURE_NPOT_BASIC, TRUE);
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP, TRUE);
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT, TRUE);
if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0) ||
_cogl_check_extension ("GL_ARB_texture_non_power_of_two", gl_extensions))
{
flags |= COGL_FEATURE_TEXTURE_NPOT
| COGL_FEATURE_TEXTURE_NPOT_BASIC
| COGL_FEATURE_TEXTURE_NPOT_MIPMAP
| COGL_FEATURE_TEXTURE_NPOT_REPEAT;
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_TEXTURE_NPOT, TRUE);
COGL_FLAGS_SET (ctx->features,
COGL_FEATURE_ID_TEXTURE_NPOT_BASIC, TRUE);
COGL_FLAGS_SET (ctx->features,
COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP, TRUE);
COGL_FLAGS_SET (ctx->features,
COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT, TRUE);
}
if (_cogl_check_extension ("GL_MESA_pack_invert", gl_extensions))
COGL_FLAGS_SET (private_features,
@@ -447,15 +483,64 @@ _cogl_driver_update_features (CoglContext *ctx,
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_DEPTH_TEXTURE, TRUE);
}
COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_PBOS, TRUE);
COGL_FLAGS_SET (private_features,
COGL_PRIVATE_FEATURE_BLEND_CONSTANT, TRUE);
if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 1) ||
_cogl_check_extension ("GL_EXT_pixel_buffer_object", gl_extensions))
COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_PBOS, TRUE);
flags |= COGL_FEATURE_SHADERS_GLSL;
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_GLSL, TRUE);
if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 1, 4) ||
_cogl_check_extension ("GL_EXT_blend_color", gl_extensions))
COGL_FLAGS_SET (private_features,
COGL_PRIVATE_FEATURE_BLEND_CONSTANT, TRUE);
flags |= COGL_FEATURE_POINT_SPRITE;
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_POINT_SPRITE, TRUE);
if (ctx->glCreateProgram)
{
flags |= COGL_FEATURE_SHADERS_GLSL;
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_GLSL, TRUE);
}
else
{
/* If all of the old GLSL extensions are available then we can fake
* the GL 2.0 GLSL support by diverting to the old function names */
if (ctx->glCreateProgramObject && /* GL_ARB_shader_objects */
ctx->glVertexAttribPointer && /* GL_ARB_vertex_shader */
_cogl_check_extension ("GL_ARB_fragment_shader", gl_extensions))
{
ctx->glCreateShader = ctx->glCreateShaderObject;
ctx->glCreateProgram = ctx->glCreateProgramObject;
ctx->glDeleteShader = ctx->glDeleteObject;
ctx->glDeleteProgram = ctx->glDeleteObject;
ctx->glAttachShader = ctx->glAttachObject;
ctx->glUseProgram = ctx->glUseProgramObject;
ctx->glGetProgramInfoLog = ctx->glGetInfoLog;
ctx->glGetShaderInfoLog = ctx->glGetInfoLog;
ctx->glGetShaderiv = ctx->glGetObjectParameteriv;
ctx->glGetProgramiv = ctx->glGetObjectParameteriv;
ctx->glDetachShader = ctx->glDetachObject;
ctx->glGetAttachedShaders = ctx->glGetAttachedObjects;
/* FIXME: there doesn't seem to be an equivalent for glIsShader
* and glIsProgram. This doesn't matter for now because Cogl
* doesn't use these but if we add support for simulating a
* GLES2 context on top of regular GL then we'll need to do
* something here */
flags |= COGL_FEATURE_SHADERS_GLSL;
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_GLSL, TRUE);
}
}
if ((COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0) ||
_cogl_check_extension ("GL_ARB_point_sprite", gl_extensions)) &&
/* If GLSL is supported then we only enable point sprite support
* too if we have glsl >= 1.2 otherwise we don't have the
* gl_PointCoord builtin which we depend on in the glsl backend.
*/
(!COGL_FLAGS_GET (ctx->features, COGL_FEATURE_ID_GLSL) ||
COGL_CHECK_GL_VERSION (ctx->glsl_major, ctx->glsl_minor, 1, 2)))
{
flags |= COGL_FEATURE_POINT_SPRITE;
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_POINT_SPRITE, TRUE);
}
if (ctx->glGenBuffers)
{
@@ -499,9 +584,17 @@ _cogl_driver_update_features (CoglContext *ctx,
COGL_FLAGS_SET (private_features,
COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE, TRUE);
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_PER_VERTEX_POINT_SIZE, TRUE);
COGL_FLAGS_SET (private_features,
COGL_PRIVATE_FEATURE_ENABLE_PROGRAM_POINT_SIZE, TRUE);
/* The per-vertex point size is only available via GLSL with the
* gl_PointSize builtin. This is only available in GL 2.0 (not the
* GLSL extensions) */
if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0))
{
COGL_FLAGS_SET (ctx->features,
COGL_FEATURE_ID_PER_VERTEX_POINT_SIZE,
TRUE);
COGL_FLAGS_SET (private_features,
COGL_PRIVATE_FEATURE_ENABLE_PROGRAM_POINT_SIZE, TRUE);
}
if (ctx->driver == COGL_DRIVER_GL)
{

View File

@@ -33,7 +33,6 @@
#include <string.h>
#include "cogl-context-private.h"
#include "cogl-error-private.h"
#include "cogl-feature-private.h"
#include "cogl-renderer-private.h"
#include "cogl-private.h"
@@ -288,15 +287,6 @@ _cogl_driver_update_features (CoglContext *context,
gl_minor = 1;
}
if (!COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0))
{
_cogl_set_error (error,
COGL_DRIVER_ERROR,
COGL_DRIVER_ERROR_INVALID_VERSION,
"OpenGL ES 2.0 or better is required");
return FALSE;
}
_cogl_feature_check_ext_functions (context,
gl_major,
gl_minor,
@@ -324,6 +314,7 @@ _cogl_driver_update_features (CoglContext *context,
COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_ANY_GL, TRUE);
COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES, TRUE);
/* Both GLES 1.1 and GLES 2.0 support point sprites in core */
flags |= COGL_FEATURE_POINT_SPRITE;
COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_POINT_SPRITE, TRUE);
@@ -350,17 +341,30 @@ _cogl_driver_update_features (CoglContext *context,
COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_DEPTH_TEXTURE, TRUE);
}
flags |= (COGL_FEATURE_TEXTURE_NPOT |
COGL_FEATURE_TEXTURE_NPOT_BASIC |
COGL_FEATURE_TEXTURE_NPOT_MIPMAP |
COGL_FEATURE_TEXTURE_NPOT_REPEAT);
COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_TEXTURE_NPOT, TRUE);
COGL_FLAGS_SET (context->features,
COGL_FEATURE_ID_TEXTURE_NPOT_BASIC, TRUE);
COGL_FLAGS_SET (context->features,
COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP, TRUE);
COGL_FLAGS_SET (context->features,
COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT, TRUE);
if (_cogl_check_extension ("GL_OES_texture_npot", gl_extensions))
{
flags |= (COGL_FEATURE_TEXTURE_NPOT |
COGL_FEATURE_TEXTURE_NPOT_BASIC |
COGL_FEATURE_TEXTURE_NPOT_MIPMAP |
COGL_FEATURE_TEXTURE_NPOT_REPEAT);
COGL_FLAGS_SET (context->features,
COGL_FEATURE_ID_TEXTURE_NPOT, TRUE);
COGL_FLAGS_SET (context->features,
COGL_FEATURE_ID_TEXTURE_NPOT_BASIC, TRUE);
COGL_FLAGS_SET (context->features,
COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP, TRUE);
COGL_FLAGS_SET (context->features,
COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT, TRUE);
}
else if (_cogl_check_extension ("GL_IMG_texture_npot", gl_extensions))
{
flags |= (COGL_FEATURE_TEXTURE_NPOT_BASIC |
COGL_FEATURE_TEXTURE_NPOT_MIPMAP);
COGL_FLAGS_SET (context->features,
COGL_FEATURE_ID_TEXTURE_NPOT_BASIC, TRUE);
COGL_FLAGS_SET (context->features,
COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP, TRUE);
}
if (context->glTexImage3D)
{

View File

@@ -99,9 +99,9 @@ typedef struct _CoglOnscreenGLX
CoglOnscreenXlib _parent;
GLXDrawable glxwin;
uint32_t last_swap_vsync_counter;
uint32_t pending_sync_notify;
uint32_t pending_complete_notify;
uint32_t pending_resize_notify;
gboolean pending_sync_notify;
gboolean pending_complete_notify;
gboolean pending_resize_notify;
GThread *swap_wait_thread;
GQueue *swap_wait_queue;
@@ -347,35 +347,35 @@ flush_pending_notifications_cb (void *data,
{
CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
gboolean pending_sync_notify = glx_onscreen->pending_sync_notify;
gboolean pending_complete_notify = glx_onscreen->pending_complete_notify;
while (glx_onscreen->pending_sync_notify > 0 ||
glx_onscreen->pending_complete_notify > 0 ||
glx_onscreen->pending_resize_notify > 0)
/* If swap_region is called then notifying the sync event could
* potentially immediately queue a subsequent pending notify so
* we need to clear the flag before invoking the callback */
glx_onscreen->pending_sync_notify = FALSE;
glx_onscreen->pending_complete_notify = FALSE;
if (pending_sync_notify)
{
if (glx_onscreen->pending_sync_notify > 0)
{
CoglFrameInfo *info =
g_queue_peek_head (&onscreen->pending_frame_infos);
CoglFrameInfo *info = g_queue_peek_head (&onscreen->pending_frame_infos);
_cogl_onscreen_notify_frame_sync (onscreen, info);
glx_onscreen->pending_sync_notify--;
}
_cogl_onscreen_notify_frame_sync (onscreen, info);
}
if (glx_onscreen->pending_complete_notify > 0)
{
CoglFrameInfo *info =
g_queue_pop_head (&onscreen->pending_frame_infos);
if (pending_complete_notify)
{
CoglFrameInfo *info = g_queue_pop_head (&onscreen->pending_frame_infos);
_cogl_onscreen_notify_complete (onscreen, info);
cogl_object_unref (info);
glx_onscreen->pending_complete_notify--;
}
_cogl_onscreen_notify_complete (onscreen, info);
if (glx_onscreen->pending_resize_notify > 0)
{
_cogl_onscreen_notify_resize (onscreen);
glx_onscreen->pending_resize_notify--;
}
cogl_object_unref (info);
}
if (glx_onscreen->pending_resize_notify)
{
_cogl_onscreen_notify_resize (onscreen);
glx_onscreen->pending_resize_notify = FALSE;
}
}
}
@@ -417,7 +417,7 @@ set_sync_pending (CoglOnscreen *onscreen)
NULL);
}
glx_onscreen->pending_sync_notify++;
glx_onscreen->pending_sync_notify = TRUE;
}
static void
@@ -440,7 +440,7 @@ set_complete_pending (CoglOnscreen *onscreen)
NULL);
}
glx_onscreen->pending_complete_notify++;
glx_onscreen->pending_complete_notify = TRUE;
}
static void
@@ -533,7 +533,7 @@ notify_resize (CoglContext *context,
NULL);
}
glx_onscreen->pending_resize_notify++;
glx_onscreen->pending_resize_notify = TRUE;
if (!xlib_onscreen->is_foreign_xwin)
{

View File

@@ -5,6 +5,7 @@ cogl_test_conformance_sources = [
'test-blend.c',
'test-depth-test.c',
'test-color-hsl.c',
'test-color-mask.c',
'test-backface-culling.c',
'test-just-vertex-shader.c',
'test-pipeline-user-matrix.c',

View File

@@ -0,0 +1,111 @@
#include <cogl/cogl.h>
#include "test-declarations.h"
#include "test-utils.h"
#define TEX_SIZE 128
#define NUM_FBOS 3
typedef struct _TestState
{
int width;
int height;
CoglTexture *tex[NUM_FBOS];
CoglFramebuffer *fbo[NUM_FBOS];
} TestState;
static void
paint (TestState *state)
{
CoglColor bg;
int i;
cogl_set_source_color4ub (255, 255, 255, 255);
/* We push the third framebuffer first so that later we can switch
back to it by popping to test that that works */
cogl_push_framebuffer (state->fbo[2]);
cogl_push_framebuffer (state->fbo[0]);
cogl_rectangle (-1.0, -1.0, 1.0, 1.0);
cogl_pop_framebuffer ();
cogl_push_framebuffer (state->fbo[1]);
cogl_rectangle (-1.0, -1.0, 1.0, 1.0);
cogl_pop_framebuffer ();
/* We should now be back on the third framebuffer */
cogl_rectangle (-1.0, -1.0, 1.0, 1.0);
cogl_pop_framebuffer ();
cogl_color_init_from_4ub (&bg, 128, 128, 128, 255);
cogl_clear (&bg, COGL_BUFFER_BIT_COLOR | COGL_BUFFER_BIT_DEPTH);
/* Render all of the textures to the screen */
for (i = 0; i < NUM_FBOS; i++)
{
CoglPipeline *pipeline = cogl_pipeline_new (test_ctx);
cogl_pipeline_set_layer_texture (pipeline, 0, state->tex[i]);
cogl_framebuffer_draw_rectangle (test_fb, pipeline,
2.0f / NUM_FBOS * i - 1.0f, -1.0f,
2.0f / NUM_FBOS * (i + 1) - 1.0f, 1.0f);
cogl_object_unref (pipeline);
}
/* Verify all of the fbos drew the right color */
for (i = 0; i < NUM_FBOS; i++)
{
uint8_t expected_colors[NUM_FBOS][4] =
{ { 0xff, 0x00, 0x00, 0xff },
{ 0x00, 0xff, 0x00, 0xff },
{ 0x00, 0x00, 0xff, 0xff } };
test_utils_check_pixel_rgb (test_fb,
state->width * (i + 0.5f) / NUM_FBOS,
state->height / 2,
expected_colors[i][0],
expected_colors[i][1],
expected_colors[i][2]);
}
}
void
test_color_mask (void)
{
TestState state;
int i;
state.width = cogl_framebuffer_get_width (test_fb);
state.height = cogl_framebuffer_get_height (test_fb);
for (i = 0; i < NUM_FBOS; i++)
{
state.tex[i] = test_utils_texture_new_with_size (test_ctx, 128, 128,
TEST_UTILS_TEXTURE_NO_ATLAS,
COGL_TEXTURE_COMPONENTS_RGB);
state.fbo[i] = cogl_offscreen_new_with_texture (state.tex[i]);
/* Clear the texture color bits */
cogl_framebuffer_clear4f (state.fbo[i],
COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
cogl_framebuffer_set_color_mask (state.fbo[i],
i == 0 ? COGL_COLOR_MASK_RED :
i == 1 ? COGL_COLOR_MASK_GREEN :
COGL_COLOR_MASK_BLUE);
}
/* XXX: we have to push/pop a framebuffer since this test currently
* uses the legacy cogl_rectangle() api. */
cogl_push_framebuffer (test_fb);
paint (&state);
cogl_pop_framebuffer ();
if (cogl_test_verbose ())
g_print ("OK\n");
}

View File

@@ -60,6 +60,7 @@ main (int argc, char **argv)
ADD_TEST (test_path, 0, 0);
ADD_TEST (test_path_clip, 0, 0);
ADD_TEST (test_depth_test, 0, 0);
ADD_TEST (test_color_mask, 0, 0);
ADD_TEST (test_backface_culling, 0, TEST_REQUIREMENT_NPOT);
ADD_TEST (test_layer_remove, 0, 0);

View File

@@ -8,6 +8,7 @@ void test_premult (void);
void test_path (void);
void test_path_clip (void);
void test_depth_test (void);
void test_color_mask (void);
void test_backface_culling (void);
void test_layer_remove (void);
void test_sparse_pipeline (void);

100
doc/meson.build Normal file
View File

@@ -0,0 +1,100 @@
# manpage
subdir('man')
# Reference manual
subdir('xml')
version_conf = configuration_data()
version_conf.set('VERSION', meson.project_version())
version_xml = configure_file(
input: 'version.xml.in',
output: 'version.xml',
configuration: version_conf
)
reference_ignored_headers = [
'config.h',
'bell.h',
'boxes-private.h',
'compositor-private.h',
'core.h',
'constraints.h',
'display-private.h',
'frame.h',
'frames.h',
'group-private.h',
'keybindings-private.h',
'main.h',
'meta-backend-private.h',
'meta-background-private.h',
'meta-barrier-private.h',
'meta-dnd-actor-private.h',
'meta-dnd-private.h',
'meta-feedback-actor-private.h',
'meta-gesture-tracker-private.h',
'meta-idle-monitor-private.h',
'meta-input-mapper-private.h',
'meta-input-settings-private.h',
'meta-monitor-manager-private.h',
'meta-remote-access-controller-private.h',
'meta-settings-private.h',
'meta-shaped-texture-private.h',
'meta-stage-private.h',
'meta-wayland-private.h',
'meta-window-actor-private.h',
'meta-window-group-private.h',
'meta-xwayland-private.h',
'meta-xwayland-selection-private.h',
'theme-private.h',
'util-private.h',
'window-private.h',
'window-x11-private.h',
'workspace-private.h',
# Test headers
'meta-backend-test.h',
'meta-monitor-manager-test.h',
'meta-wayland-egl-stream.h',
'meta-wayland-inhibit-shortcuts.h',
'meta-wayland-text-input.h',
'meta-xwayland-grab-keyboard.h',
]
# Make sure we ignore the wayland headers
if have_wayland
foreach proto : wayland_protocols
protocol_name = proto[0]
protocol_type = proto[1]
if protocol_type == 'stable'
output_base = protocol_name
elif protocol_type == 'private'
output_base = protocol_name
elif protocol_type == 'third-party'
output_base = protocol_name
else
protocol_version = proto[2]
output_base = '@0@-@1@-@2@'.format(protocol_name,
protocol_type,
protocol_version)
endif
proto_header = '@0@-server-protocol.h'.format(output_base)
reference_ignored_headers += proto_header
endforeach
endif
gnome.gtkdoc(meson.project_name(),
main_sgml: 'mutter-docs.sgml',
src_dir: [
include_directories('../src'),
],
dependencies: _libmutter_public_symbols_dep,
gobject_typesfile: 'mutter.types',
scan_args: [
'--rebuild-types',
'--ignore-headers=' + ' '.join(reference_ignored_headers),
'--ignore-decorators=META_EXPORT|META_EXPORT_TEST',
],
install: true,
)

110
doc/mutter-docs.sgml Normal file
View File

@@ -0,0 +1,110 @@
<?xml version="1.0"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
[
<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
<!ENTITY % gtkdocentities SYSTEM "xml/gtkdocentities.ent">
%gtkdocentities;
]>
<book id="index">
<bookinfo>
<title>Mutter Reference Manual</title>
<releaseinfo>
For &package_string;.
The latest version of this documentation can be found on-line at
<ulink role="online-location" url="http://[SERVER]/&package_name;/index.html">http://[SERVER]/&package_name;/</ulink>.
</releaseinfo>
</bookinfo>
<chapter>
<title>General</title>
<xi:include href="xml/meta-backend.xml"/>
<xi:include href="xml/meta-clutter-backend-native.xml"/>
<xi:include href="xml/meta-renderer.xml"/>
<xi:include href="xml/meta-stage.xml"/>
</chapter>
<chapter>
<title>Clutter actors</title>
<xi:include href="xml/meta-window-actor.xml"/>
<xi:include href="xml/meta-window-group.xml"/>
<xi:include href="xml/meta-background-actor.xml"/>
<xi:include href="xml/meta-background-group.xml"/>
<xi:include href="xml/meta-surface-actor.xml"/>
<xi:include href="xml/meta-shaped-texture.xml"/>
</chapter>
<chapter>
<title>Plugins</title>
<xi:include href="xml/meta-plugin.xml"/>
<xi:include href="xml/meta-plugin-manager.xml"/>
</chapter>
<chapter>
<title>Cursor management</title>
<xi:include href="xml/meta-cursor-tracker.xml"/>
<xi:include href="xml/meta-cursor.xml"/>
<xi:include href="xml/meta-cursor-renderer.xml"/>
<xi:include href="xml/meta-pointer-constraint.xml"/>
</chapter>
<chapter>
<title>Monitor management</title>
<xi:include href="xml/meta-monitor-manager.xml"/>
<xi:include href="xml/meta-monitor-manager-dummy.xml"/>
<xi:include href="xml/meta-monitor-config-manager.xml"/>
<xi:include href="xml/meta-logical-monitor.xml"/>
<xi:include href="xml/meta-monitor.xml"/>
<xi:include href="xml/meta-monitor-transform.xml"/>
</chapter>
<chapter>
<title>X11</title>
<xi:include href="xml/meta-backend-x11.xml"/>
<xi:include href="xml/meta-monitor-manager-xrandr.xml"/>
<xi:include href="xml/meta-window-actor-x11.xml"/>
<xi:include href="xml/meta-surface-actor-x11.xml"/>
</chapter>
<chapter>
<title>Native / Wayland</title>
<xi:include href="xml/meta-backend-native.xml"/>
<xi:include href="xml/meta-monitor-manager-kms.xml"/>
<xi:include href="xml/meta-renderer-native.xml"/>
<xi:include href="xml/meta-window-actor-wayland.xml"/>
<xi:include href="xml/meta-surface-actor-wayland.xml"/>
</chapter>
<chapter>
<title>Screencast</title>
<xi:include href="xml/meta-screen-cast.xml"/>
<xi:include href="xml/meta-screen-cast-session.xml"/>
<xi:include href="xml/meta-screen-cast-window.xml"/>
<xi:include href="xml/meta-screen-cast-stream.xml"/>
<xi:include href="xml/meta-screen-cast-window-stream.xml"/>
<xi:include href="xml/meta-screen-cast-monitor-stream.xml"/>
<xi:include href="xml/meta-screen-cast-stream-src.xml"/>
<xi:include href="xml/meta-screen-cast-window-stream-src.xml"/>
<xi:include href="xml/meta-screen-cast-monitor-stream-src.xml"/>
</chapter>
<chapter>
<title>Remote desktop</title>
<xi:include href="xml/meta-remote-desktop.xml"/>
<xi:include href="xml/meta-dbus-remote-desktop.xml"/>
</chapter>
<chapter id="object-tree">
<title>Object Hierarchy</title>
<xi:include href="xml/tree_index.sgml"/>
</chapter>
<index id="api-index-full">
<title>API Index</title>
<xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
</index>
<index id="deprecated-api-index" role="deprecated">
<title>Index of deprecated API</title>
<xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
</index>
<xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
</book>

1
doc/version.xml.in Normal file
View File

@@ -0,0 +1 @@
@VERSION@

View File

@@ -0,0 +1,7 @@
<!ENTITY package @PACKAGE@>
<!ENTITY package_bugreport @PACKAGE_BUGREPORT@>
<!ENTITY package_name @PACKAGE_NAME@>
<!ENTITY package_string @PACKAGE_STRING@>
<!ENTITY package_tarname @PACKAGE_TARNAME@>
<!ENTITY package_url @PACKAGE_URL@>
<!ENTITY package_version @PACKAGE_VERSION@>

13
doc/xml/meson.build Normal file
View File

@@ -0,0 +1,13 @@
gtkdoc_entities_cdata = configuration_data()
gtkdoc_entities_cdata.set_quoted('PACKAGE', meson.project_name())
gtkdoc_entities_cdata.set_quoted('PACKAGE_BUGREPORT', 'https://gitlab.gnome.org/GNOME/mutter/issues/new')
gtkdoc_entities_cdata.set_quoted('PACKAGE_NAME', meson.project_name())
gtkdoc_entities_cdata.set_quoted('PACKAGE_STRING', '@0@ - @1@'.format(meson.project_name(), meson.project_version()))
gtkdoc_entities_cdata.set_quoted('PACKAGE_TARNAME', 'mutter.tar.xz')
gtkdoc_entities_cdata.set_quoted('PACKAGE_URL', 'https://gitlab.gnome.org/GNOME/mutter/')
gtkdoc_entities_cdata.set_quoted('PACKAGE_VERSION', meson.project_version())
configure_file(
input: 'gtkdocentities.ent.in',
output: 'gtkdocentities.ent',
configuration: gtkdoc_entities_cdata,
)

View File

@@ -1,5 +1,5 @@
project('mutter', 'c',
version: '3.32.1',
version: '3.32.0',
meson_version: '>= 0.48.0',
license: 'GPLv2+'
)
@@ -370,7 +370,7 @@ subdir('clutter')
subdir('data')
subdir('src')
subdir('po')
subdir('doc/man')
subdir('doc')
output = [
'',

View File

@@ -20,7 +20,7 @@
*/
/**
* SECTION:cursor-tracker
* SECTION:meta-cursor-tracker
* @title: MetaCursorTracker
* @short_description: Mutter cursor tracking helper. Originally only
* tracking the cursor image, now more of a "core

View File

@@ -3787,13 +3787,16 @@ gpu_kms_is_hardware_rendering (MetaRendererNative *renderer_native,
return data->secondary.is_hardware_rendering;
}
static EGLDisplay
init_gbm_egl_display (MetaRendererNative *renderer_native,
struct gbm_device *gbm_device,
GError **error)
static MetaRendererNativeGpuData *
create_renderer_gpu_data_gbm (MetaRendererNative *renderer_native,
MetaGpuKms *gpu_kms,
GError **error)
{
MetaEgl *egl = meta_renderer_native_get_egl (renderer_native);
struct gbm_device *gbm_device;
EGLDisplay egl_display;
int kms_fd;
MetaRendererNativeGpuData *renderer_gpu_data;
if (!meta_egl_has_extensions (egl, EGL_NO_DISPLAY, NULL,
"EGL_MESA_platform_gbm",
@@ -3805,31 +3808,9 @@ init_gbm_egl_display (MetaRendererNative *renderer_native,
g_set_error (error, G_IO_ERROR,
G_IO_ERROR_FAILED,
"Missing extension for GBM renderer: EGL_KHR_platform_gbm");
return EGL_NO_DISPLAY;
return NULL;
}
egl_display = meta_egl_get_platform_display (egl,
EGL_PLATFORM_GBM_KHR,
gbm_device, NULL, error);
if (egl_display == EGL_NO_DISPLAY)
return EGL_NO_DISPLAY;
if (!meta_egl_initialize (egl, egl_display, error))
return EGL_NO_DISPLAY;
return egl_display;
}
static MetaRendererNativeGpuData *
create_renderer_gpu_data_gbm (MetaRendererNative *renderer_native,
MetaGpuKms *gpu_kms,
GError **error)
{
struct gbm_device *gbm_device;
int kms_fd;
MetaRendererNativeGpuData *renderer_gpu_data;
g_autoptr (GError) local_error = NULL;
kms_fd = meta_gpu_kms_get_fd (gpu_kms);
gbm_device = gbm_create_device (kms_fd);
@@ -3841,25 +3822,26 @@ create_renderer_gpu_data_gbm (MetaRendererNative *renderer_native,
return NULL;
}
egl_display = meta_egl_get_platform_display (egl,
EGL_PLATFORM_GBM_KHR,
gbm_device, NULL, error);
if (egl_display == EGL_NO_DISPLAY)
{
gbm_device_destroy (gbm_device);
return NULL;
}
if (!meta_egl_initialize (egl, egl_display, error))
return NULL;
renderer_gpu_data = meta_create_renderer_native_gpu_data (gpu_kms);
renderer_gpu_data->renderer_native = renderer_native;
renderer_gpu_data->gbm.device = gbm_device;
renderer_gpu_data->mode = META_RENDERER_NATIVE_MODE_GBM;
renderer_gpu_data->egl_display = init_gbm_egl_display (renderer_native,
gbm_device,
&local_error);
if (renderer_gpu_data->egl_display == EGL_NO_DISPLAY)
{
g_debug ("GBM EGL init for %s failed: %s",
meta_gpu_kms_get_file_path (gpu_kms),
local_error->message);
init_secondary_gpu_data_cpu (renderer_gpu_data);
return renderer_gpu_data;
}
renderer_gpu_data->egl_display = egl_display;
init_secondary_gpu_data (renderer_gpu_data);
return renderer_gpu_data;
}
@@ -4152,8 +4134,8 @@ on_gpu_added (MetaMonitorManager *monitor_manager,
}
static MetaGpuKms *
choose_primary_gpu_unchecked (MetaMonitorManager *manager,
MetaRendererNative *renderer_native)
choose_primary_gpu (MetaMonitorManager *manager,
MetaRendererNative *renderer_native)
{
GList *gpus = meta_monitor_manager_get_gpus (manager);
GList *l;
@@ -4202,28 +4184,6 @@ choose_primary_gpu_unchecked (MetaMonitorManager *manager,
return NULL;
}
static MetaGpuKms *
choose_primary_gpu (MetaMonitorManager *manager,
MetaRendererNative *renderer_native,
GError **error)
{
MetaGpuKms *gpu_kms;
MetaRendererNativeGpuData *renderer_gpu_data;
gpu_kms = choose_primary_gpu_unchecked (manager, renderer_native);
renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native,
gpu_kms);
if (renderer_gpu_data->egl_display == EGL_NO_DISPLAY)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"The GPU %s chosen as primary is not supported by EGL.",
meta_gpu_kms_get_file_path (gpu_kms));
return NULL;
}
return gpu_kms;
}
static gboolean
meta_renderer_native_initable_init (GInitable *initable,
GCancellable *cancellable,
@@ -4247,10 +4207,7 @@ meta_renderer_native_initable_init (GInitable *initable,
}
renderer_native->primary_gpu_kms = choose_primary_gpu (monitor_manager,
renderer_native,
error);
if (!renderer_native->primary_gpu_kms)
return FALSE;
renderer_native);
return TRUE;
}

View File

@@ -316,7 +316,6 @@ get_base_pipeline (MetaShapedTexture *stex,
CoglContext *ctx)
{
CoglPipeline *pipeline;
CoglMatrix matrix;
if (stex->base_pipeline)
return stex->base_pipeline;
@@ -330,11 +329,11 @@ get_base_pipeline (MetaShapedTexture *stex,
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
cogl_pipeline_set_layer_wrap_mode_t (pipeline, 1,
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
cogl_matrix_init_identity (&matrix);
if (!stex->is_y_inverted)
{
CoglMatrix matrix;
cogl_matrix_init_identity (&matrix);
cogl_matrix_scale (&matrix, 1, -1, 1);
cogl_matrix_translate (&matrix, 0, -1, 0);
cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix);
@@ -342,9 +341,10 @@ get_base_pipeline (MetaShapedTexture *stex,
if (stex->transform != META_MONITOR_TRANSFORM_NORMAL)
{
CoglMatrix matrix;
CoglEuler euler;
cogl_matrix_translate (&matrix, 0.5, 0.5, 0.0);
cogl_matrix_init_translation (&matrix, 0.5, 0.5, 0.0);
switch (stex->transform)
{
case META_MONITOR_TRANSFORM_90:
@@ -373,45 +373,11 @@ get_base_pipeline (MetaShapedTexture *stex,
}
cogl_matrix_rotate_euler (&matrix, &euler);
cogl_matrix_translate (&matrix, -0.5, -0.5, 0.0);
cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix);
cogl_pipeline_set_layer_matrix (pipeline, 1, &matrix);
}
if (stex->has_viewport_src_rect)
{
ClutterActor *actor = CLUTTER_ACTOR (stex);
double tex_scale;
clutter_actor_get_scale (actor, &tex_scale, NULL);
if (meta_monitor_transform_is_rotated (stex->transform))
{
cogl_matrix_scale (&matrix,
stex->viewport_src_rect.size.width /
(stex->tex_height * tex_scale),
stex->viewport_src_rect.size.height /
(stex->tex_width * tex_scale),
1);
}
else
{
cogl_matrix_scale (&matrix,
stex->viewport_src_rect.size.width /
(stex->tex_width * tex_scale),
stex->viewport_src_rect.size.height /
(stex->tex_height * tex_scale),
1);
}
cogl_matrix_translate (&matrix,
stex->viewport_src_rect.origin.x /
stex->viewport_src_rect.size.width,
stex->viewport_src_rect.origin.y /
stex->viewport_src_rect.size.height,
0);
}
cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix);
cogl_pipeline_set_layer_matrix (pipeline, 1, &matrix);
if (stex->snippet)
cogl_pipeline_add_layer_snippet (pipeline, 0, stex->snippet);
@@ -487,10 +453,48 @@ paint_clipped_rectangle (MetaShapedTexture *stex,
alloc_width = alloc->x2 - alloc->x1;
alloc_height = alloc->y2 - alloc->y1;
coords[0] = rect->x / alloc_width;
coords[1] = rect->y / alloc_height;
coords[2] = (rect->x + rect->width) / alloc_width;
coords[3] = (rect->y + rect->height) / alloc_height;
if (stex->has_viewport_src_rect)
{
double tex_scale;
float src_x;
float src_y;
float src_width;
float src_height;
clutter_actor_get_scale (CLUTTER_ACTOR (stex), &tex_scale, NULL);
src_x = stex->viewport_src_rect.origin.x / tex_scale;
src_y = stex->viewport_src_rect.origin.y / tex_scale;
src_width = stex->viewport_src_rect.size.width / tex_scale;
src_height = stex->viewport_src_rect.size.height / tex_scale;
coords[0] = rect->x * src_width / alloc_width + src_x;
coords[1] = rect->y * src_height / alloc_height + src_y;
coords[2] = rect->width * src_width / alloc_width + coords[0];
coords[3] = rect->height * src_height / alloc_height + coords[1];
if (meta_monitor_transform_is_rotated (stex->transform))
{
coords[0] /= stex->tex_height;
coords[1] /= stex->tex_width;
coords[2] /= stex->tex_height;
coords[3] /= stex->tex_width;
}
else
{
coords[0] /= stex->tex_width;
coords[1] /= stex->tex_height;
coords[2] /= stex->tex_width;
coords[3] /= stex->tex_height;
}
}
else
{
coords[0] = rect->x / alloc_width;
coords[1] = rect->y / alloc_height;
coords[2] = (rect->x + rect->width) / alloc_width;
coords[3] = (rect->y + rect->height) / alloc_height;
}
coords[4] = coords[0];
coords[5] = coords[1];
@@ -757,10 +761,11 @@ do_paint (MetaShapedTexture *stex,
else
{
/* 3) blended_tex_region is NULL. Do a full paint. */
cogl_framebuffer_draw_rectangle (fb, blended_pipeline,
0, 0,
alloc.x2 - alloc.x1,
alloc.y2 - alloc.y1);
paint_clipped_rectangle (stex,
fb,
blended_pipeline,
&tex_rect,
&alloc);
}
}
@@ -1202,7 +1207,6 @@ meta_shaped_texture_set_viewport_src_rect (MetaShapedTexture *stex,
{
stex->has_viewport_src_rect = TRUE;
stex->viewport_src_rect = *src_rect;
meta_shaped_texture_reset_pipelines (stex);
invalidate_size (stex);
}
}
@@ -1210,11 +1214,7 @@ meta_shaped_texture_set_viewport_src_rect (MetaShapedTexture *stex,
void
meta_shaped_texture_reset_viewport_src_rect (MetaShapedTexture *stex)
{
if (!stex->has_viewport_src_rect)
return;
stex->has_viewport_src_rect = FALSE;
meta_shaped_texture_reset_pipelines (stex);
invalidate_size (stex);
}
@@ -1237,9 +1237,6 @@ meta_shaped_texture_set_viewport_dst_size (MetaShapedTexture *stex,
void
meta_shaped_texture_reset_viewport_dst_size (MetaShapedTexture *stex)
{
if (!stex->has_viewport_dst_size)
return;
stex->has_viewport_dst_size = FALSE;
invalidate_size (stex);
}

View File

@@ -2236,7 +2236,7 @@ meta_display_get_tab_list (MetaDisplay *display,
MetaWindow *l_window = w->data;
if (l_window->wm_state_demands_attention &&
!meta_window_located_on_workspace (l_window, workspace) &&
l_window->workspace != workspace &&
IN_TAB_CHAIN (l_window, type))
tab_list = g_list_prepend (tab_list, l_window);
}

View File

@@ -2214,8 +2214,6 @@ meta_keybindings_process_event (MetaDisplay *display,
{
case CLUTTER_BUTTON_PRESS:
case CLUTTER_BUTTON_RELEASE:
case CLUTTER_TOUCH_BEGIN:
case CLUTTER_TOUCH_END:
keys->overlay_key_only_pressed = FALSE;
return FALSE;

View File

@@ -37,7 +37,7 @@
* OpenOffice or whatever seems to stop launching - people
* might decide they need to launch it again.
*/
#define STARTUP_TIMEOUT_MS 15000
#define STARTUP_TIMEOUT 15000000
enum
{
@@ -59,12 +59,6 @@ enum
N_SEQ_PROPS
};
enum
{
SEQ_COMPLETE,
N_SEQ_SIGNALS
};
enum
{
CHANGED,
@@ -73,7 +67,6 @@ enum
static guint sn_signals[N_SIGNALS];
static GParamSpec *sn_props[N_PROPS];
static guint seq_signals[N_SEQ_SIGNALS];
static GParamSpec *seq_props[N_SEQ_PROPS];
typedef struct
@@ -113,26 +106,12 @@ G_DEFINE_TYPE_WITH_PRIVATE (MetaStartupSequence,
static void meta_startup_notification_ensure_timeout (MetaStartupNotification *sn);
static gboolean
meta_startup_notification_has_pending_sequences (MetaStartupNotification *sn)
{
GSList *l;
for (l = sn->startup_sequences; l; l = l->next)
{
if (!meta_startup_sequence_get_completed (l->data))
return TRUE;
}
return FALSE;
}
static void
meta_startup_notification_update_feedback (MetaStartupNotification *sn)
{
MetaDisplay *display = sn->display;
if (meta_startup_notification_has_pending_sequences (sn))
if (sn->startup_sequences != NULL)
{
meta_topic (META_DEBUG_STARTUP,
"Setting busy cursor\n");
@@ -260,14 +239,6 @@ meta_startup_sequence_class_init (MetaStartupSequenceClass *klass)
object_class->set_property = meta_startup_sequence_set_property;
object_class->get_property = meta_startup_sequence_get_property;
seq_signals[SEQ_COMPLETE] =
g_signal_new ("complete",
META_TYPE_STARTUP_SEQUENCE,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (MetaStartupSequenceClass, complete),
NULL, NULL, NULL,
G_TYPE_NONE, 0);
seq_props[PROP_SEQ_ID] =
g_param_spec_string ("id",
"ID",
@@ -346,6 +317,7 @@ meta_startup_sequence_get_timestamp (MetaStartupSequence *seq)
void
meta_startup_sequence_complete (MetaStartupSequence *seq)
{
MetaStartupSequenceClass *klass;
MetaStartupSequencePrivate *priv;
g_return_if_fail (META_IS_STARTUP_SEQUENCE (seq));
@@ -355,7 +327,10 @@ meta_startup_sequence_complete (MetaStartupSequence *seq)
return;
priv->completed = TRUE;
g_signal_emit (seq, seq_signals[SEQ_COMPLETE], 0);
klass = META_STARTUP_SEQUENCE_GET_CLASS (seq);
if (klass->complete)
klass->complete (seq);
}
gboolean
@@ -424,22 +399,12 @@ meta_startup_sequence_get_wmclass (MetaStartupSequence *seq)
return priv->wmclass;
}
static void
on_sequence_completed (MetaStartupSequence *seq,
MetaStartupNotification *sn)
{
meta_startup_notification_update_feedback (sn);
g_signal_emit (sn, sn_signals[CHANGED], 0, seq);
}
void
meta_startup_notification_add_sequence (MetaStartupNotification *sn,
MetaStartupSequence *seq)
{
sn->startup_sequences = g_slist_prepend (sn->startup_sequences,
g_object_ref (seq));
g_signal_connect (seq, "complete",
G_CALLBACK (on_sequence_completed), sn);
meta_startup_notification_ensure_timeout (sn);
meta_startup_notification_update_feedback (sn);
@@ -460,10 +425,10 @@ collect_timed_out_foreach (void *element,
meta_topic (META_DEBUG_STARTUP,
"Sequence used %" G_GINT64_FORMAT " ms vs. %d max: %s\n",
elapsed, STARTUP_TIMEOUT_MS,
elapsed, STARTUP_TIMEOUT,
meta_startup_sequence_get_id (sequence));
if (elapsed > STARTUP_TIMEOUT_MS)
if (elapsed > STARTUP_TIMEOUT)
ctod->list = g_slist_prepend (ctod->list, sequence);
}
@@ -475,7 +440,7 @@ startup_sequence_timeout (void *data)
GSList *l;
ctod.list = NULL;
ctod.now = g_get_monotonic_time () / 1000;
ctod.now = g_get_monotonic_time ();
g_slist_foreach (sn->startup_sequences,
collect_timed_out_foreach,
&ctod);
@@ -529,8 +494,6 @@ meta_startup_notification_remove_sequence (MetaStartupNotification *sn,
sn->startup_sequences = g_slist_remove (sn->startup_sequences, seq);
meta_startup_notification_update_feedback (sn);
g_signal_handlers_disconnect_by_func (seq, on_sequence_completed, sn);
if (sn->startup_sequences == NULL &&
sn->startup_sequence_timeout != 0)
{

View File

@@ -1012,22 +1012,5 @@ meta_generate_random_id (GRand *rand,
return id;
}
void
meta_add_clutter_debug_flags (ClutterDebugFlag debug_flags,
ClutterDrawDebugFlag draw_flags,
ClutterPickDebugFlag pick_flags)
{
clutter_add_debug_flags (debug_flags, draw_flags, pick_flags);
}
void
meta_remove_clutter_debug_flags (ClutterDebugFlag debug_flags,
ClutterDrawDebugFlag draw_flags,
ClutterPickDebugFlag pick_flags)
{
clutter_remove_debug_flags (debug_flags, draw_flags, pick_flags);
}
/* eof util.c */

View File

@@ -778,6 +778,32 @@ libmutter_dep = declare_dependency(
],
)
# Interal library for gtk-doc (we need symbol visibility)
_libmutter_public_symbols = library(libmutter_name + '-public-symbols',
sources: [
mutter_sources,
mutter_built_sources,
],
include_directories: mutter_includes,
c_args: mutter_c_args,
dependencies: [
libmutter_cogl_dep,
libmutter_clutter_dep,
mutter_deps,
],
)
_libmutter_public_symbols_dep = declare_dependency(
link_with: _libmutter_public_symbols,
include_directories: mutter_includes,
sources: mutter_built_sources,
dependencies: [
libmutter_cogl_dep,
libmutter_clutter_dep,
mutter_deps,
],
)
executable('mutter',
sources: [
files('core/mutter.c'),

View File

@@ -226,14 +226,4 @@ typedef enum
META_EXPORT
MetaLocaleDirection meta_get_locale_direction (void);
META_EXPORT
void meta_add_clutter_debug_flags (ClutterDebugFlag debug_flags,
ClutterDrawDebugFlag draw_flags,
ClutterPickDebugFlag pick_flags);
META_EXPORT
void meta_remove_clutter_debug_flags (ClutterDebugFlag debug_flags,
ClutterDrawDebugFlag draw_flags,
ClutterPickDebugFlag pick_flags);
#endif /* META_UTIL_H */

View File

@@ -624,14 +624,14 @@ meta_xdg_output_manager_get_xdg_output (struct wl_client *client,
wl_resource_get_version (resource),
id);
wl_resource_set_implementation (xdg_output_resource,
&meta_xdg_output_interface,
NULL, meta_xdg_output_destructor);
wayland_output = wl_resource_get_user_data (output);
if (!wayland_output)
return;
wl_resource_set_implementation (xdg_output_resource,
&meta_xdg_output_interface,
wayland_output, meta_xdg_output_destructor);
wayland_output->xdg_output_resources =
g_list_prepend (wayland_output->xdg_output_resources, xdg_output_resource);

View File

@@ -35,6 +35,9 @@
typedef struct _MetaXWaylandSelection MetaXWaylandSelection;
/**
* MetaWaylandFrameCallback: (skip)
*/
typedef struct
{
struct wl_list link;

View File

@@ -151,7 +151,7 @@ meta_startup_sequence_x11_new (SnStartupSequence *seq)
{
gint64 timestamp;
timestamp = sn_startup_sequence_get_timestamp (seq);
timestamp = sn_startup_sequence_get_timestamp (seq) * 1000;
return g_object_new (META_TYPE_STARTUP_SEQUENCE_X11,
"id", sn_startup_sequence_get_id (seq),
"icon-name", sn_startup_sequence_get_icon_name (seq),