Compare commits
124 Commits
3.37.2
...
wip/carlos
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c90f39ace5 | ||
![]() |
2e5b767c01 | ||
![]() |
f511f94aa2 | ||
![]() |
3187fe8ebc | ||
![]() |
f5c8e0d96d | ||
![]() |
c3d1320343 | ||
![]() |
5c5dcd58b5 | ||
![]() |
6ea0f8facc | ||
![]() |
0c1e5b4ee5 | ||
![]() |
ad50d2cfc4 | ||
![]() |
1398c6dfa4 | ||
![]() |
ab9f241cc5 | ||
![]() |
1f5d6a01f5 | ||
![]() |
ca79073014 | ||
![]() |
0b6f5c6f55 | ||
![]() |
e2c2a332e6 | ||
![]() |
245977e525 | ||
![]() |
e03c75bac7 | ||
![]() |
4ff58cc63f | ||
![]() |
462df7e61a | ||
![]() |
1285619bcf | ||
![]() |
d6f5ac5603 | ||
![]() |
d133f94f8f | ||
![]() |
e216d9c6ad | ||
![]() |
79050004b0 | ||
![]() |
e5ea8f5483 | ||
![]() |
0ab1a9fa44 | ||
![]() |
cb0cc42651 | ||
![]() |
b36cfb5bdc | ||
![]() |
7539de2320 | ||
![]() |
8de91f1053 | ||
![]() |
45c14f74b4 | ||
![]() |
d4457d1f7f | ||
![]() |
0ba15df57c | ||
![]() |
e09ac67698 | ||
![]() |
e6a93326bf | ||
![]() |
fb474fb612 | ||
![]() |
d12dc993d1 | ||
![]() |
6414b8c45f | ||
![]() |
19b467aa01 | ||
![]() |
e089e53b24 | ||
![]() |
bad1a7fd0c | ||
![]() |
51a8193c16 | ||
![]() |
94fb82137f | ||
![]() |
49408e8f9f | ||
![]() |
77d359cdc3 | ||
![]() |
590b9b8c86 | ||
![]() |
09078762ac | ||
![]() |
352c2ec7b8 | ||
![]() |
4b37c2e446 | ||
![]() |
980ece9a4b | ||
![]() |
1ce9e379d9 | ||
![]() |
4a4f2d8264 | ||
![]() |
4920b5064d | ||
![]() |
26ddb07066 | ||
![]() |
574b49ed95 | ||
![]() |
6697b0d069 | ||
![]() |
092c5304a9 | ||
![]() |
c3fc6025b1 | ||
![]() |
1406348be4 | ||
![]() |
46e3d20057 | ||
![]() |
9bcf1d0238 | ||
![]() |
b69111d8e6 | ||
![]() |
f71316c850 | ||
![]() |
9186b6d6b0 | ||
![]() |
55719afcbf | ||
![]() |
e063947a16 | ||
![]() |
a42eed0231 | ||
![]() |
f4fd92d8e8 | ||
![]() |
2ebd43cba9 | ||
![]() |
2724f36527 | ||
![]() |
569a183828 | ||
![]() |
620dcf3364 | ||
![]() |
eb9cd3857d | ||
![]() |
0bfb995bff | ||
![]() |
932340a989 | ||
![]() |
ca0156e9a7 | ||
![]() |
6d75b4fc53 | ||
![]() |
6bd382ad23 | ||
![]() |
a1b3d1a2a7 | ||
![]() |
53f61f3778 | ||
![]() |
74c0d9140c | ||
![]() |
268336c21a | ||
![]() |
49e983b06e | ||
![]() |
0f97196d84 | ||
![]() |
18c792d6f8 | ||
![]() |
675a97d58e | ||
![]() |
8127494e52 | ||
![]() |
670f4f22fe | ||
![]() |
e27d2702a8 | ||
![]() |
dfe33897db | ||
![]() |
90c20b185b | ||
![]() |
4d7c8d68bc | ||
![]() |
455de5d6d3 | ||
![]() |
99c9f4c1fa | ||
![]() |
dd32ff018a | ||
![]() |
019643bad0 | ||
![]() |
a031ac067e | ||
![]() |
f712387325 | ||
![]() |
1eaf9e5f63 | ||
![]() |
7222bdde57 | ||
![]() |
007d27fa40 | ||
![]() |
01609de587 | ||
![]() |
83ee122fad | ||
![]() |
55302dbb38 | ||
![]() |
7876018755 | ||
![]() |
e3c332fa10 | ||
![]() |
faa831f2f6 | ||
![]() |
1a915f06cf | ||
![]() |
6754195580 | ||
![]() |
25f9406e69 | ||
![]() |
9fc428f2e7 | ||
![]() |
a05dd813da | ||
![]() |
08b30d6fe2 | ||
![]() |
84f55d38dd | ||
![]() |
75b5e079cf | ||
![]() |
d742f9331c | ||
![]() |
420ca31f0b | ||
![]() |
73da901cd3 | ||
![]() |
dd16fac0c7 | ||
![]() |
1b2af2891f | ||
![]() |
050c21c24f | ||
![]() |
7b45de941b | ||
![]() |
8d84449941 |
@@ -60,17 +60,6 @@ static const gchar * cally_util_get_toolkit_name (void);
|
||||
static const gchar * cally_util_get_toolkit_version (void);
|
||||
|
||||
/* private */
|
||||
static void cally_util_simulate_snooper_install (void);
|
||||
static void cally_util_simulate_snooper_remove (void);
|
||||
static gboolean cally_key_snooper (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer user_data);
|
||||
static void cally_util_stage_added_cb (ClutterStageManager *stage_manager,
|
||||
ClutterStage *stage,
|
||||
gpointer data);
|
||||
static void cally_util_stage_removed_cb (ClutterStageManager *stage_manager,
|
||||
ClutterStage *stage,
|
||||
gpointer data);
|
||||
static gboolean notify_hf (gpointer key,
|
||||
gpointer value,
|
||||
gpointer data);
|
||||
@@ -153,12 +142,8 @@ cally_util_add_key_event_listener (AtkKeySnoopFunc listener,
|
||||
CallyKeyEventInfo *event_info = NULL;
|
||||
|
||||
if (!key_listener_list)
|
||||
{
|
||||
key_listener_list = g_hash_table_new_full (NULL, NULL, NULL, g_free);
|
||||
|
||||
cally_util_simulate_snooper_install ();
|
||||
}
|
||||
|
||||
event_info = g_new (CallyKeyEventInfo, 1);
|
||||
event_info->listener = listener;
|
||||
event_info->func_data = data;
|
||||
@@ -179,75 +164,11 @@ cally_util_remove_key_event_listener (guint remove_listener)
|
||||
{
|
||||
g_hash_table_destroy (key_listener_list);
|
||||
key_listener_list = NULL;
|
||||
cally_util_simulate_snooper_remove ();
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------ PRIVATE FUNCTIONS ------------------------- */
|
||||
|
||||
/* Trying to emulate gtk_key_snooper install (a kind of wrapper). This
|
||||
could be implemented without it, but I will maintain it in this
|
||||
way, so if in the future clutter implements it natively it would be
|
||||
easier the transition */
|
||||
static void
|
||||
cally_util_simulate_snooper_install (void)
|
||||
{
|
||||
ClutterStageManager *stage_manager = NULL;
|
||||
ClutterStage *stage = NULL;
|
||||
GSList *stage_list = NULL;
|
||||
GSList *iter = NULL;
|
||||
|
||||
stage_manager = clutter_stage_manager_get_default ();
|
||||
stage_list = clutter_stage_manager_list_stages (stage_manager);
|
||||
|
||||
for (iter = stage_list; iter != NULL; iter = g_slist_next (iter))
|
||||
{
|
||||
stage = CLUTTER_STAGE (iter->data);
|
||||
|
||||
g_signal_connect (G_OBJECT (stage), "captured-event",
|
||||
G_CALLBACK (cally_key_snooper), NULL);
|
||||
}
|
||||
|
||||
g_signal_connect (G_OBJECT (stage_manager), "stage-added",
|
||||
G_CALLBACK (cally_util_stage_added_cb), cally_key_snooper);
|
||||
g_signal_connect (G_OBJECT (stage_manager), "stage-removed",
|
||||
G_CALLBACK (cally_util_stage_removed_cb), cally_key_snooper);
|
||||
|
||||
g_slist_free (stage_list);
|
||||
}
|
||||
|
||||
static void
|
||||
cally_util_simulate_snooper_remove (void)
|
||||
{
|
||||
ClutterStageManager *stage_manager = NULL;
|
||||
ClutterStage *stage = NULL;
|
||||
GSList *stage_list = NULL;
|
||||
GSList *iter = NULL;
|
||||
gint num = 0;
|
||||
|
||||
stage_manager = clutter_stage_manager_get_default ();
|
||||
stage_list = clutter_stage_manager_list_stages (stage_manager);
|
||||
|
||||
for (iter = stage_list; iter != NULL; iter = g_slist_next (iter))
|
||||
{
|
||||
stage = CLUTTER_STAGE (iter->data);
|
||||
|
||||
num += g_signal_handlers_disconnect_by_func (stage, cally_key_snooper, NULL);
|
||||
}
|
||||
|
||||
g_signal_handlers_disconnect_by_func (G_OBJECT (stage_manager),
|
||||
G_CALLBACK (cally_util_stage_added_cb),
|
||||
cally_key_snooper);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (G_OBJECT (stage_manager),
|
||||
G_CALLBACK (cally_util_stage_removed_cb),
|
||||
cally_key_snooper);
|
||||
|
||||
#ifdef CALLY_DEBUG
|
||||
g_print ("Number of snooper callbacks disconnected: %i\n", num);
|
||||
#endif
|
||||
}
|
||||
|
||||
static AtkKeyEventStruct *
|
||||
atk_key_event_from_clutter_event_key (ClutterKeyEvent *clutter_event,
|
||||
gunichar password_char)
|
||||
@@ -384,59 +305,34 @@ check_key_visibility (ClutterEvent *event)
|
||||
return DEFAULT_PASSWORD_CHAR;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
cally_key_snooper (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer user_data)
|
||||
gboolean
|
||||
cally_snoop_key_event (ClutterKeyEvent *key)
|
||||
{
|
||||
ClutterEvent *event = (ClutterEvent *) key;
|
||||
AtkKeyEventStruct *key_event = NULL;
|
||||
gint consumed = 0;
|
||||
gboolean consumed = FALSE;
|
||||
gunichar password_char = 0;
|
||||
|
||||
/* filter key events */
|
||||
if ((event->type != CLUTTER_KEY_PRESS) && (event->type != CLUTTER_KEY_RELEASE))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
password_char = check_key_visibility (event);
|
||||
return FALSE;
|
||||
|
||||
if (key_listener_list)
|
||||
{
|
||||
GHashTable *new_hash = g_hash_table_new (NULL, NULL);
|
||||
|
||||
g_hash_table_foreach (key_listener_list, insert_hf, new_hash);
|
||||
key_event = atk_key_event_from_clutter_event_key ((ClutterKeyEvent *)event,
|
||||
password_char);
|
||||
password_char = check_key_visibility (event);
|
||||
key_event = atk_key_event_from_clutter_event_key (key, password_char);
|
||||
/* func data is inside the hash table */
|
||||
consumed = g_hash_table_foreach_steal (new_hash, notify_hf, key_event);
|
||||
consumed = g_hash_table_foreach_steal (new_hash, notify_hf, key_event) > 0;
|
||||
g_hash_table_destroy (new_hash);
|
||||
|
||||
g_free (key_event->string);
|
||||
g_free (key_event);
|
||||
}
|
||||
|
||||
return (consumed ? 1 : 0);
|
||||
}
|
||||
|
||||
static void
|
||||
cally_util_stage_added_cb (ClutterStageManager *stage_manager,
|
||||
ClutterStage *stage,
|
||||
gpointer data)
|
||||
{
|
||||
GCallback cally_key_snooper_cb = G_CALLBACK (data);
|
||||
|
||||
g_signal_connect (G_OBJECT (stage), "captured-event", cally_key_snooper_cb, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
cally_util_stage_removed_cb (ClutterStageManager *stage_manager,
|
||||
ClutterStage *stage,
|
||||
gpointer data)
|
||||
{
|
||||
GCallback cally_key_snooper_cb = G_CALLBACK (data);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (stage, cally_key_snooper_cb, NULL);
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -79,6 +79,8 @@ GType cally_util_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void _cally_util_override_atk_util (void);
|
||||
|
||||
gboolean cally_snoop_key_event (ClutterKeyEvent *key);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CALLY_UTIL_H__ */
|
||||
|
@@ -615,6 +615,32 @@ clutter_actor_box_scale (ClutterActorBox *box,
|
||||
box->y2 *= scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_box_is_initialized:
|
||||
* @box: a #ClutterActorBox
|
||||
*
|
||||
* Checks if @box has been initialized, a #ClutterActorBox is uninitialized
|
||||
* if it has a size of -1 at an origin of 0, 0.
|
||||
*
|
||||
* Returns: %TRUE if the box is uninitialized, %FALSE if it isn't
|
||||
*/
|
||||
gboolean
|
||||
clutter_actor_box_is_initialized (ClutterActorBox *box)
|
||||
{
|
||||
gboolean x1_uninitialized, x2_uninitialized;
|
||||
gboolean y1_uninitialized, y2_uninitialized;
|
||||
|
||||
g_return_val_if_fail (box != NULL, TRUE);
|
||||
|
||||
x1_uninitialized = isinf (box->x1);
|
||||
x2_uninitialized = isinf (box->x2) && signbit (box->x2);
|
||||
y1_uninitialized = isinf (box->y1);
|
||||
y2_uninitialized = isinf (box->y2) && signbit (box->y2);
|
||||
|
||||
return !x1_uninitialized || !x2_uninitialized ||
|
||||
!y1_uninitialized || !y2_uninitialized;
|
||||
}
|
||||
|
||||
G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterActorBox, clutter_actor_box,
|
||||
clutter_actor_box_copy,
|
||||
clutter_actor_box_free,
|
||||
|
@@ -313,7 +313,7 @@ void _clutter_actor_detach_clone
|
||||
void _clutter_actor_queue_redraw_on_clones (ClutterActor *actor);
|
||||
void _clutter_actor_queue_relayout_on_clones (ClutterActor *actor);
|
||||
void _clutter_actor_queue_only_relayout (ClutterActor *actor);
|
||||
void _clutter_actor_queue_update_resource_scale_recursive (ClutterActor *actor);
|
||||
void clutter_actor_clear_stage_views_recursive (ClutterActor *actor);
|
||||
|
||||
gboolean _clutter_actor_get_real_resource_scale (ClutterActor *actor,
|
||||
float *resource_scale);
|
||||
@@ -321,6 +321,8 @@ gboolean _clutter_actor_get_real_resource_scale
|
||||
ClutterPaintNode * clutter_actor_create_texture_paint_node (ClutterActor *self,
|
||||
CoglTexture *texture);
|
||||
|
||||
void clutter_actor_update_stage_views (ClutterActor *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_ACTOR_PRIVATE_H__ */
|
||||
|
@@ -446,7 +446,8 @@
|
||||
* ]|
|
||||
*
|
||||
* - the initial `@` is mandatory
|
||||
* - the `section` fragment can be one between "actions", "constraints" and "effects"
|
||||
* - the `section` fragment can be one between "actions", "constraints", "content",
|
||||
* and "effects"
|
||||
* - the `meta-name` fragment is the name of the action, effect, or constraint, as
|
||||
* specified by the #ClutterActorMeta:name property of #ClutterActorMeta
|
||||
* - the `property-name` fragment is the name of the action, effect, or constraint
|
||||
@@ -811,6 +812,9 @@ struct _ClutterActorPrivate
|
||||
|
||||
gulong resolution_changed_id;
|
||||
gulong font_changed_id;
|
||||
gulong layout_changed_id;
|
||||
|
||||
GList *stage_views;
|
||||
|
||||
/* bitfields: KEEP AT THE END */
|
||||
|
||||
@@ -854,6 +858,7 @@ struct _ClutterActorPrivate
|
||||
guint had_effects_on_last_paint_volume_update : 1;
|
||||
guint needs_compute_resource_scale : 1;
|
||||
guint absolute_origin_changed : 1;
|
||||
guint needs_update_stage_views : 1;
|
||||
};
|
||||
|
||||
enum
|
||||
@@ -1016,6 +1021,7 @@ enum
|
||||
TRANSITIONS_COMPLETED,
|
||||
TOUCH_EVENT,
|
||||
TRANSITION_STOPPED,
|
||||
STAGE_VIEWS_CHANGED,
|
||||
|
||||
LAST_SIGNAL
|
||||
};
|
||||
@@ -1613,6 +1619,22 @@ clutter_actor_update_map_state (ClutterActor *self,
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
queue_update_stage_views (ClutterActor *actor)
|
||||
{
|
||||
while (actor && !actor->priv->needs_update_stage_views)
|
||||
{
|
||||
actor->priv->needs_update_stage_views = TRUE;
|
||||
|
||||
/* We don't really need to update the stage-views of the actors up the
|
||||
* hierarchy, we set the flag anyway though so we can avoid traversing
|
||||
* the whole scenegraph when looking for actors which need an update
|
||||
* in clutter_actor_update_stage_views().
|
||||
*/
|
||||
actor = actor->priv->parent;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_actor_real_map (ClutterActor *self)
|
||||
{
|
||||
@@ -1627,6 +1649,18 @@ clutter_actor_real_map (ClutterActor *self)
|
||||
|
||||
self->priv->needs_paint_volume_update = TRUE;
|
||||
|
||||
/* We skip unmapped actors when updating the stage-views list, so if
|
||||
* an actors list got invalidated while it was unmapped make sure to
|
||||
* set priv->needs_update_stage_views to TRUE for all actors up the
|
||||
* hierarchy now.
|
||||
*/
|
||||
if (self->priv->needs_update_stage_views)
|
||||
{
|
||||
/* Avoid the early return in queue_update_stage_views() */
|
||||
self->priv->needs_update_stage_views = FALSE;
|
||||
queue_update_stage_views (self);
|
||||
}
|
||||
|
||||
clutter_actor_ensure_resource_scale (self);
|
||||
|
||||
/* notify on parent mapped before potentially mapping
|
||||
@@ -2409,8 +2443,7 @@ clutter_actor_real_get_preferred_width (ClutterActor *self,
|
||||
{
|
||||
ClutterActorPrivate *priv = self->priv;
|
||||
|
||||
if (priv->n_children != 0 &&
|
||||
priv->layout_manager != NULL)
|
||||
if (priv->layout_manager != NULL)
|
||||
{
|
||||
ClutterContainer *container = CLUTTER_CONTAINER (self);
|
||||
|
||||
@@ -2449,8 +2482,7 @@ clutter_actor_real_get_preferred_height (ClutterActor *self,
|
||||
{
|
||||
ClutterActorPrivate *priv = self->priv;
|
||||
|
||||
if (priv->n_children != 0 &&
|
||||
priv->layout_manager != NULL)
|
||||
if (priv->layout_manager != NULL)
|
||||
{
|
||||
ClutterContainer *container = CLUTTER_CONTAINER (self);
|
||||
|
||||
@@ -2564,6 +2596,7 @@ static void
|
||||
absolute_allocation_changed (ClutterActor *actor)
|
||||
{
|
||||
actor->priv->needs_compute_resource_scale = TRUE;
|
||||
queue_update_stage_views (actor);
|
||||
}
|
||||
|
||||
static ClutterActorTraverseVisitFlags
|
||||
@@ -4281,6 +4314,7 @@ typedef enum
|
||||
REMOVE_CHILD_FLUSH_QUEUE = 1 << 4,
|
||||
REMOVE_CHILD_NOTIFY_FIRST_LAST = 1 << 5,
|
||||
REMOVE_CHILD_STOP_TRANSITIONS = 1 << 6,
|
||||
REMOVE_CHILD_CLEAR_STAGE_VIEWS = 1 << 7,
|
||||
|
||||
/* default flags for public API */
|
||||
REMOVE_CHILD_DEFAULT_FLAGS = REMOVE_CHILD_STOP_TRANSITIONS |
|
||||
@@ -4289,14 +4323,16 @@ typedef enum
|
||||
REMOVE_CHILD_EMIT_ACTOR_REMOVED |
|
||||
REMOVE_CHILD_CHECK_STATE |
|
||||
REMOVE_CHILD_FLUSH_QUEUE |
|
||||
REMOVE_CHILD_NOTIFY_FIRST_LAST,
|
||||
REMOVE_CHILD_NOTIFY_FIRST_LAST |
|
||||
REMOVE_CHILD_CLEAR_STAGE_VIEWS,
|
||||
|
||||
/* flags for legacy/deprecated API */
|
||||
REMOVE_CHILD_LEGACY_FLAGS = REMOVE_CHILD_STOP_TRANSITIONS |
|
||||
REMOVE_CHILD_CHECK_STATE |
|
||||
REMOVE_CHILD_FLUSH_QUEUE |
|
||||
REMOVE_CHILD_EMIT_PARENT_SET |
|
||||
REMOVE_CHILD_NOTIFY_FIRST_LAST
|
||||
REMOVE_CHILD_NOTIFY_FIRST_LAST |
|
||||
REMOVE_CHILD_CLEAR_STAGE_VIEWS
|
||||
} ClutterActorRemoveChildFlags;
|
||||
|
||||
/*< private >
|
||||
@@ -4318,6 +4354,7 @@ clutter_actor_remove_child_internal (ClutterActor *self,
|
||||
gboolean notify_first_last;
|
||||
gboolean was_mapped;
|
||||
gboolean stop_transitions;
|
||||
gboolean clear_stage_views;
|
||||
GObject *obj;
|
||||
|
||||
if (self == child)
|
||||
@@ -4334,6 +4371,7 @@ clutter_actor_remove_child_internal (ClutterActor *self,
|
||||
flush_queue = (flags & REMOVE_CHILD_FLUSH_QUEUE) != 0;
|
||||
notify_first_last = (flags & REMOVE_CHILD_NOTIFY_FIRST_LAST) != 0;
|
||||
stop_transitions = (flags & REMOVE_CHILD_STOP_TRANSITIONS) != 0;
|
||||
clear_stage_views = (flags & REMOVE_CHILD_CLEAR_STAGE_VIEWS) != 0;
|
||||
|
||||
obj = G_OBJECT (self);
|
||||
g_object_freeze_notify (obj);
|
||||
@@ -4407,6 +4445,13 @@ clutter_actor_remove_child_internal (ClutterActor *self,
|
||||
clutter_actor_queue_compute_expand (self);
|
||||
}
|
||||
|
||||
/* Only actors which are attached to a stage get notified about changes
|
||||
* to the stage views, so make sure all the stage-views lists are
|
||||
* cleared as the child and its children leave the actor tree.
|
||||
*/
|
||||
if (clear_stage_views && !CLUTTER_ACTOR_IN_DESTRUCTION (child))
|
||||
clutter_actor_clear_stage_views_recursive (child);
|
||||
|
||||
if (emit_parent_set && !CLUTTER_ACTOR_IN_DESTRUCTION (child))
|
||||
{
|
||||
child->priv->needs_compute_resource_scale = TRUE;
|
||||
@@ -5197,7 +5242,7 @@ clutter_actor_set_property (GObject *object,
|
||||
break;
|
||||
|
||||
case PROP_OFFSCREEN_REDIRECT:
|
||||
clutter_actor_set_offscreen_redirect (actor, g_value_get_enum (value));
|
||||
clutter_actor_set_offscreen_redirect (actor, g_value_get_flags (value));
|
||||
break;
|
||||
|
||||
case PROP_NAME:
|
||||
@@ -6062,6 +6107,7 @@ clutter_actor_dispose (GObject *object)
|
||||
|
||||
if (priv->layout_manager != NULL)
|
||||
{
|
||||
g_clear_signal_handler (&priv->layout_changed_id, priv->layout_manager);
|
||||
clutter_layout_manager_set_container (priv->layout_manager, NULL);
|
||||
g_clear_object (&priv->layout_manager);
|
||||
}
|
||||
@@ -6078,6 +6124,8 @@ clutter_actor_dispose (GObject *object)
|
||||
priv->clones = NULL;
|
||||
}
|
||||
|
||||
g_clear_pointer (&priv->stage_views, g_list_free);
|
||||
|
||||
G_OBJECT_CLASS (clutter_actor_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
@@ -8614,6 +8662,27 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
g_signal_set_va_marshaller (actor_signals[TOUCH_EVENT],
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
_clutter_marshal_BOOLEAN__BOXEDv);
|
||||
|
||||
/**
|
||||
* ClutterActor::stage-views-changed:
|
||||
* @actor: a #ClutterActor
|
||||
*
|
||||
* The ::stage-views-changed signal is emitted when the position or
|
||||
* size an actor is being painted at have changed so that it's visible
|
||||
* on different stage views.
|
||||
*
|
||||
* This signal is also emitted when the actor gets detached from the stage
|
||||
* or when the views of the stage have been invalidated and will be
|
||||
* replaced; it's not emitted when the actor gets hidden.
|
||||
*/
|
||||
actor_signals[STAGE_VIEWS_CHANGED] =
|
||||
g_signal_new (I_("stage-views-changed"),
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -8623,6 +8692,8 @@ clutter_actor_init (ClutterActor *self)
|
||||
|
||||
self->priv = priv = clutter_actor_get_instance_private (self);
|
||||
|
||||
priv->allocation = (ClutterActorBox) CLUTTER_ACTOR_BOX_UNINITIALIZED;
|
||||
|
||||
priv->opacity = 0xff;
|
||||
priv->show_on_set_parent = TRUE;
|
||||
priv->resource_scale = -1.0f;
|
||||
@@ -8632,6 +8703,7 @@ clutter_actor_init (ClutterActor *self)
|
||||
priv->needs_allocation = TRUE;
|
||||
priv->needs_paint_volume_update = TRUE;
|
||||
priv->needs_compute_resource_scale = TRUE;
|
||||
priv->needs_update_stage_views = TRUE;
|
||||
|
||||
priv->cached_width_age = 1;
|
||||
priv->cached_height_age = 1;
|
||||
@@ -13605,138 +13677,107 @@ clutter_actor_set_child_at_index (ClutterActor *self,
|
||||
gboolean
|
||||
clutter_actor_event (ClutterActor *actor,
|
||||
const ClutterEvent *event,
|
||||
gboolean capture)
|
||||
gboolean capture)
|
||||
{
|
||||
gboolean retval = FALSE;
|
||||
gint signal_num = -1;
|
||||
GQuark detail = 0;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), FALSE);
|
||||
g_return_val_if_fail (event != NULL, FALSE);
|
||||
|
||||
g_object_ref (actor);
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case CLUTTER_NOTHING:
|
||||
break;
|
||||
case CLUTTER_BUTTON_PRESS:
|
||||
signal_num = BUTTON_PRESS_EVENT;
|
||||
detail = quark_button;
|
||||
break;
|
||||
case CLUTTER_BUTTON_RELEASE:
|
||||
signal_num = BUTTON_RELEASE_EVENT;
|
||||
detail = quark_button;
|
||||
break;
|
||||
case CLUTTER_SCROLL:
|
||||
signal_num = SCROLL_EVENT;
|
||||
detail = quark_scroll;
|
||||
break;
|
||||
case CLUTTER_KEY_PRESS:
|
||||
signal_num = KEY_PRESS_EVENT;
|
||||
detail = quark_key;
|
||||
break;
|
||||
case CLUTTER_KEY_RELEASE:
|
||||
signal_num = KEY_RELEASE_EVENT;
|
||||
detail = quark_key;
|
||||
break;
|
||||
case CLUTTER_MOTION:
|
||||
signal_num = MOTION_EVENT;
|
||||
detail = quark_motion;
|
||||
break;
|
||||
case CLUTTER_ENTER:
|
||||
signal_num = ENTER_EVENT;
|
||||
detail = quark_pointer_focus;
|
||||
break;
|
||||
case CLUTTER_LEAVE:
|
||||
signal_num = LEAVE_EVENT;
|
||||
detail = quark_pointer_focus;
|
||||
break;
|
||||
case CLUTTER_TOUCH_BEGIN:
|
||||
case CLUTTER_TOUCH_END:
|
||||
case CLUTTER_TOUCH_UPDATE:
|
||||
case CLUTTER_TOUCH_CANCEL:
|
||||
signal_num = TOUCH_EVENT;
|
||||
detail = quark_touch;
|
||||
break;
|
||||
case CLUTTER_TOUCHPAD_PINCH:
|
||||
case CLUTTER_TOUCHPAD_SWIPE:
|
||||
signal_num = -1;
|
||||
detail = quark_touchpad;
|
||||
break;
|
||||
case CLUTTER_PROXIMITY_IN:
|
||||
case CLUTTER_PROXIMITY_OUT:
|
||||
signal_num = -1;
|
||||
detail = quark_proximity;
|
||||
break;
|
||||
case CLUTTER_PAD_BUTTON_PRESS:
|
||||
case CLUTTER_PAD_BUTTON_RELEASE:
|
||||
case CLUTTER_PAD_STRIP:
|
||||
case CLUTTER_PAD_RING:
|
||||
signal_num = -1;
|
||||
detail = quark_pad;
|
||||
break;
|
||||
case CLUTTER_DELETE:
|
||||
signal_num = -1;
|
||||
detail = quark_delete;
|
||||
break;
|
||||
case CLUTTER_DESTROY_NOTIFY:
|
||||
signal_num = -1;
|
||||
detail = quark_destroy;
|
||||
break;
|
||||
case CLUTTER_CLIENT_MESSAGE:
|
||||
signal_num = -1;
|
||||
detail = quark_client;
|
||||
break;
|
||||
case CLUTTER_STAGE_STATE:
|
||||
signal_num = -1;
|
||||
detail = quark_stage;
|
||||
break;
|
||||
case CLUTTER_EVENT_LAST: /* Just keep compiler warnings quiet */
|
||||
break;
|
||||
}
|
||||
|
||||
if (capture)
|
||||
g_signal_emit (actor, actor_signals[CAPTURED_EVENT], detail, event, &retval);
|
||||
else
|
||||
{
|
||||
GQuark detail = 0;
|
||||
g_signal_emit (actor, actor_signals[EVENT], 0, event, &retval);
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case CLUTTER_NOTHING:
|
||||
break;
|
||||
case CLUTTER_KEY_PRESS:
|
||||
case CLUTTER_KEY_RELEASE:
|
||||
detail = quark_key;
|
||||
break;
|
||||
case CLUTTER_MOTION:
|
||||
detail = quark_motion;
|
||||
break;
|
||||
case CLUTTER_ENTER:
|
||||
case CLUTTER_LEAVE:
|
||||
detail = quark_pointer_focus;
|
||||
break;
|
||||
case CLUTTER_BUTTON_PRESS:
|
||||
case CLUTTER_BUTTON_RELEASE:
|
||||
detail = quark_button;
|
||||
break;
|
||||
case CLUTTER_SCROLL:
|
||||
detail = quark_scroll;
|
||||
break;
|
||||
case CLUTTER_STAGE_STATE:
|
||||
detail = quark_stage;
|
||||
break;
|
||||
case CLUTTER_DESTROY_NOTIFY:
|
||||
detail = quark_destroy;
|
||||
break;
|
||||
case CLUTTER_CLIENT_MESSAGE:
|
||||
detail = quark_client;
|
||||
break;
|
||||
case CLUTTER_DELETE:
|
||||
detail = quark_delete;
|
||||
break;
|
||||
case CLUTTER_TOUCH_BEGIN:
|
||||
case CLUTTER_TOUCH_UPDATE:
|
||||
case CLUTTER_TOUCH_END:
|
||||
case CLUTTER_TOUCH_CANCEL:
|
||||
detail = quark_touch;
|
||||
break;
|
||||
case CLUTTER_TOUCHPAD_PINCH:
|
||||
case CLUTTER_TOUCHPAD_SWIPE:
|
||||
detail = quark_touchpad;
|
||||
break;
|
||||
case CLUTTER_PROXIMITY_IN:
|
||||
case CLUTTER_PROXIMITY_OUT:
|
||||
detail = quark_proximity;
|
||||
break;
|
||||
case CLUTTER_PAD_BUTTON_PRESS:
|
||||
case CLUTTER_PAD_BUTTON_RELEASE:
|
||||
case CLUTTER_PAD_STRIP:
|
||||
case CLUTTER_PAD_RING:
|
||||
detail = quark_pad;
|
||||
break;
|
||||
case CLUTTER_EVENT_LAST: /* Just keep compiler warnings quiet */
|
||||
break;
|
||||
}
|
||||
|
||||
g_signal_emit (actor,
|
||||
actor_signals[CAPTURED_EVENT],
|
||||
detail,
|
||||
event,
|
||||
&retval);
|
||||
goto out;
|
||||
if (!retval && signal_num != -1)
|
||||
g_signal_emit (actor, actor_signals[signal_num], 0, event, &retval);
|
||||
}
|
||||
|
||||
g_signal_emit (actor, actor_signals[EVENT], 0, event, &retval);
|
||||
|
||||
if (!retval)
|
||||
{
|
||||
switch (event->type)
|
||||
{
|
||||
case CLUTTER_NOTHING:
|
||||
break;
|
||||
case CLUTTER_BUTTON_PRESS:
|
||||
signal_num = BUTTON_PRESS_EVENT;
|
||||
break;
|
||||
case CLUTTER_BUTTON_RELEASE:
|
||||
signal_num = BUTTON_RELEASE_EVENT;
|
||||
break;
|
||||
case CLUTTER_SCROLL:
|
||||
signal_num = SCROLL_EVENT;
|
||||
break;
|
||||
case CLUTTER_KEY_PRESS:
|
||||
signal_num = KEY_PRESS_EVENT;
|
||||
break;
|
||||
case CLUTTER_KEY_RELEASE:
|
||||
signal_num = KEY_RELEASE_EVENT;
|
||||
break;
|
||||
case CLUTTER_MOTION:
|
||||
signal_num = MOTION_EVENT;
|
||||
break;
|
||||
case CLUTTER_ENTER:
|
||||
signal_num = ENTER_EVENT;
|
||||
break;
|
||||
case CLUTTER_LEAVE:
|
||||
signal_num = LEAVE_EVENT;
|
||||
break;
|
||||
case CLUTTER_TOUCH_BEGIN:
|
||||
case CLUTTER_TOUCH_END:
|
||||
case CLUTTER_TOUCH_UPDATE:
|
||||
case CLUTTER_TOUCH_CANCEL:
|
||||
signal_num = TOUCH_EVENT;
|
||||
break;
|
||||
case CLUTTER_DELETE:
|
||||
case CLUTTER_DESTROY_NOTIFY:
|
||||
case CLUTTER_CLIENT_MESSAGE:
|
||||
default:
|
||||
signal_num = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (signal_num != -1)
|
||||
g_signal_emit (actor, actor_signals[signal_num], 0,
|
||||
event, &retval);
|
||||
}
|
||||
|
||||
out:
|
||||
g_object_unref (actor);
|
||||
|
||||
return retval;
|
||||
@@ -14551,6 +14592,37 @@ get_layout_from_animation_property (ClutterActor *actor,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_content_from_animation_property (ClutterActor *actor,
|
||||
const gchar *name,
|
||||
gchar **name_p)
|
||||
{
|
||||
g_auto (GStrv) tokens = NULL;
|
||||
|
||||
if (!g_str_has_prefix (name, "@content"))
|
||||
return FALSE;
|
||||
|
||||
if (!actor->priv->content)
|
||||
{
|
||||
CLUTTER_NOTE (ANIMATION, "No ClutterContent available for '%s'",
|
||||
name + 1);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
tokens = g_strsplit (name, ".", -1);
|
||||
if (tokens == NULL || g_strv_length (tokens) != 2)
|
||||
{
|
||||
CLUTTER_NOTE (ANIMATION, "Invalid property name '%s'",
|
||||
name + 1);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (name_p != NULL)
|
||||
*name_p = g_strdup (tokens[1]);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static ClutterActorMeta *
|
||||
get_meta_from_animation_property (ClutterActor *actor,
|
||||
const gchar *name,
|
||||
@@ -14618,6 +14690,7 @@ clutter_actor_find_property (ClutterAnimatable *animatable,
|
||||
GObjectClass *klass = NULL;
|
||||
GParamSpec *pspec = NULL;
|
||||
gchar *p_name = NULL;
|
||||
gboolean use_content = FALSE;
|
||||
gboolean use_layout;
|
||||
|
||||
use_layout = get_layout_from_animation_property (actor,
|
||||
@@ -14625,6 +14698,11 @@ clutter_actor_find_property (ClutterAnimatable *animatable,
|
||||
&p_name);
|
||||
|
||||
if (!use_layout)
|
||||
use_content = get_content_from_animation_property (actor,
|
||||
property_name,
|
||||
&p_name);
|
||||
|
||||
if (!use_layout && !use_content)
|
||||
meta = get_meta_from_animation_property (actor,
|
||||
property_name,
|
||||
&p_name);
|
||||
@@ -14639,6 +14717,12 @@ clutter_actor_find_property (ClutterAnimatable *animatable,
|
||||
{
|
||||
klass = G_OBJECT_GET_CLASS (actor->priv->layout_manager);
|
||||
|
||||
pspec = g_object_class_find_property (klass, p_name);
|
||||
}
|
||||
else if (use_content)
|
||||
{
|
||||
klass = G_OBJECT_GET_CLASS (actor->priv->content);
|
||||
|
||||
pspec = g_object_class_find_property (klass, p_name);
|
||||
}
|
||||
else
|
||||
@@ -14661,6 +14745,7 @@ clutter_actor_get_initial_state (ClutterAnimatable *animatable,
|
||||
ClutterActor *actor = CLUTTER_ACTOR (animatable);
|
||||
ClutterActorMeta *meta = NULL;
|
||||
gchar *p_name = NULL;
|
||||
gboolean use_content = FALSE;
|
||||
gboolean use_layout;
|
||||
|
||||
use_layout = get_layout_from_animation_property (actor,
|
||||
@@ -14668,6 +14753,11 @@ clutter_actor_get_initial_state (ClutterAnimatable *animatable,
|
||||
&p_name);
|
||||
|
||||
if (!use_layout)
|
||||
use_content = get_content_from_animation_property (actor,
|
||||
property_name,
|
||||
&p_name);
|
||||
|
||||
if (!use_layout && !use_content)
|
||||
meta = get_meta_from_animation_property (actor,
|
||||
property_name,
|
||||
&p_name);
|
||||
@@ -14676,6 +14766,8 @@ clutter_actor_get_initial_state (ClutterAnimatable *animatable,
|
||||
g_object_get_property (G_OBJECT (meta), p_name, initial);
|
||||
else if (use_layout)
|
||||
g_object_get_property (G_OBJECT (actor->priv->layout_manager), p_name, initial);
|
||||
else if (use_content)
|
||||
g_object_get_property (G_OBJECT (actor->priv->content), p_name, initial);
|
||||
else
|
||||
g_object_get_property (G_OBJECT (animatable), property_name, initial);
|
||||
|
||||
@@ -14826,6 +14918,7 @@ clutter_actor_set_final_state (ClutterAnimatable *animatable,
|
||||
ClutterActor *actor = CLUTTER_ACTOR (animatable);
|
||||
ClutterActorMeta *meta = NULL;
|
||||
gchar *p_name = NULL;
|
||||
gboolean use_content = FALSE;
|
||||
gboolean use_layout;
|
||||
|
||||
use_layout = get_layout_from_animation_property (actor,
|
||||
@@ -14833,6 +14926,11 @@ clutter_actor_set_final_state (ClutterAnimatable *animatable,
|
||||
&p_name);
|
||||
|
||||
if (!use_layout)
|
||||
use_content = get_content_from_animation_property (actor,
|
||||
property_name,
|
||||
&p_name);
|
||||
|
||||
if (!use_layout && !use_content)
|
||||
meta = get_meta_from_animation_property (actor,
|
||||
property_name,
|
||||
&p_name);
|
||||
@@ -14841,6 +14939,8 @@ clutter_actor_set_final_state (ClutterAnimatable *animatable,
|
||||
g_object_set_property (G_OBJECT (meta), p_name, final);
|
||||
else if (use_layout)
|
||||
g_object_set_property (G_OBJECT (actor->priv->layout_manager), p_name, final);
|
||||
else if (use_content)
|
||||
g_object_set_property (G_OBJECT (actor->priv->content), p_name, final);
|
||||
else
|
||||
{
|
||||
GObjectClass *obj_class = G_OBJECT_GET_CLASS (animatable);
|
||||
@@ -17419,17 +17519,27 @@ _clutter_actor_get_resource_scale_for_rect (ClutterActor *self,
|
||||
float *resource_scale)
|
||||
{
|
||||
ClutterActor *stage;
|
||||
g_autoptr (GList) views = NULL;
|
||||
GList *l;
|
||||
float max_scale = 0;
|
||||
|
||||
stage = _clutter_actor_get_stage_internal (self);
|
||||
if (!stage)
|
||||
return FALSE;
|
||||
|
||||
if (!_clutter_stage_get_max_view_scale_factor_for_rect (CLUTTER_STAGE (stage),
|
||||
bounding_rect,
|
||||
&max_scale))
|
||||
views = clutter_stage_get_views_for_rect (CLUTTER_STAGE (stage),
|
||||
bounding_rect);
|
||||
|
||||
if (!views)
|
||||
return FALSE;
|
||||
|
||||
for (l = views; l; l = l->next)
|
||||
{
|
||||
ClutterStageView *view = l->data;
|
||||
|
||||
max_scale = MAX (clutter_stage_view_get_scale (view), max_scale);
|
||||
}
|
||||
|
||||
*resource_scale = max_scale;
|
||||
|
||||
return TRUE;
|
||||
@@ -17505,20 +17615,29 @@ _clutter_actor_compute_resource_scale (ClutterActor *self,
|
||||
}
|
||||
|
||||
static ClutterActorTraverseVisitFlags
|
||||
queue_update_resource_scale_cb (ClutterActor *actor,
|
||||
int depth,
|
||||
void *user_data)
|
||||
clear_stage_views_cb (ClutterActor *actor,
|
||||
int depth,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_autoptr (GList) old_stage_views = NULL;
|
||||
|
||||
actor->priv->needs_update_stage_views = TRUE;
|
||||
actor->priv->needs_compute_resource_scale = TRUE;
|
||||
|
||||
old_stage_views = g_steal_pointer (&actor->priv->stage_views);
|
||||
|
||||
if (old_stage_views)
|
||||
g_signal_emit (actor, actor_signals[STAGE_VIEWS_CHANGED], 0);
|
||||
|
||||
return CLUTTER_ACTOR_TRAVERSE_VISIT_CONTINUE;
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_actor_queue_update_resource_scale_recursive (ClutterActor *self)
|
||||
clutter_actor_clear_stage_views_recursive (ClutterActor *self)
|
||||
{
|
||||
_clutter_actor_traverse (self,
|
||||
CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST,
|
||||
queue_update_resource_scale_cb,
|
||||
clear_stage_views_cb,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
@@ -17610,6 +17729,125 @@ clutter_actor_get_resource_scale (ClutterActor *self,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
sorted_lists_equal (GList *list_a,
|
||||
GList *list_b)
|
||||
{
|
||||
GList *a, *b;
|
||||
|
||||
if (!list_a && !list_b)
|
||||
return TRUE;
|
||||
|
||||
for (a = list_a, b = list_b;
|
||||
a && b;
|
||||
a = a->next, b = b->next)
|
||||
{
|
||||
if (a->data != b->data)
|
||||
break;
|
||||
|
||||
if (!a->next && !b->next)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
update_stage_views (ClutterActor *self)
|
||||
{
|
||||
ClutterActorPrivate *priv = self->priv;
|
||||
g_autoptr (GList) old_stage_views = NULL;
|
||||
ClutterStage *stage;
|
||||
graphene_rect_t bounding_rect;
|
||||
|
||||
old_stage_views = g_steal_pointer (&priv->stage_views);
|
||||
|
||||
if (priv->needs_allocation)
|
||||
{
|
||||
g_warning ("Can't update stage views actor %s is on because it needs an "
|
||||
"allocation.", _clutter_actor_get_debug_name (self));
|
||||
goto out;
|
||||
}
|
||||
|
||||
stage = CLUTTER_STAGE (_clutter_actor_get_stage_internal (self));
|
||||
g_return_if_fail (stage);
|
||||
|
||||
clutter_actor_get_transformed_position (self,
|
||||
&bounding_rect.origin.x,
|
||||
&bounding_rect.origin.y);
|
||||
clutter_actor_get_transformed_size (self,
|
||||
&bounding_rect.size.width,
|
||||
&bounding_rect.size.height);
|
||||
|
||||
if (bounding_rect.size.width == 0.0 ||
|
||||
bounding_rect.size.height == 0.0)
|
||||
goto out;
|
||||
|
||||
priv->stage_views = clutter_stage_get_views_for_rect (stage,
|
||||
&bounding_rect);
|
||||
|
||||
out:
|
||||
if (g_signal_has_handler_pending (self, actor_signals[STAGE_VIEWS_CHANGED],
|
||||
0, TRUE))
|
||||
{
|
||||
if (!sorted_lists_equal (old_stage_views, priv->stage_views))
|
||||
g_signal_emit (self, actor_signals[STAGE_VIEWS_CHANGED], 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
clutter_actor_update_stage_views (ClutterActor *self)
|
||||
{
|
||||
ClutterActorPrivate *priv = self->priv;
|
||||
ClutterActor *child;
|
||||
|
||||
if (!CLUTTER_ACTOR_IS_MAPPED (self) ||
|
||||
CLUTTER_ACTOR_IN_DESTRUCTION (self))
|
||||
return;
|
||||
|
||||
if (!priv->needs_update_stage_views)
|
||||
return;
|
||||
|
||||
update_stage_views (self);
|
||||
|
||||
priv->needs_update_stage_views = FALSE;
|
||||
|
||||
for (child = priv->first_child; child; child = child->priv->next_sibling)
|
||||
clutter_actor_update_stage_views (child);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_peek_stage_views:
|
||||
* @self: A #ClutterActor
|
||||
*
|
||||
* Retrieves the list of #ClutterStageView<!-- -->s the actor is being
|
||||
* painted on.
|
||||
*
|
||||
* If this function is called during the paint cycle, the list is guaranteed
|
||||
* to be up-to-date, if called outside the paint cycle, the list will
|
||||
* contain the views the actor was painted on last.
|
||||
*
|
||||
* The list returned by this function is not updated when the actors
|
||||
* visibility changes: If an actor gets hidden and is not being painted
|
||||
* anymore, this function will return the list of views the actor was
|
||||
* painted on last.
|
||||
*
|
||||
* If an actor is not attached to a stage (realized), this function will
|
||||
* always return an empty list.
|
||||
*
|
||||
* Returns: (transfer none) (element-type Clutter.StageView): The list of
|
||||
* #ClutterStageView<!-- -->s the actor is being painted on. The list and
|
||||
* its contents are owned by the #ClutterActor and the list may not be
|
||||
* freed or modified.
|
||||
*/
|
||||
GList *
|
||||
clutter_actor_peek_stage_views (ClutterActor *self)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE);
|
||||
|
||||
return self->priv->stage_views;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_has_overlaps:
|
||||
* @self: A #ClutterActor
|
||||
@@ -17971,9 +18209,7 @@ clutter_actor_set_layout_manager (ClutterActor *self,
|
||||
|
||||
if (priv->layout_manager != NULL)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (priv->layout_manager,
|
||||
G_CALLBACK (on_layout_manager_changed),
|
||||
self);
|
||||
g_clear_signal_handler (&priv->layout_changed_id, priv->layout_manager);
|
||||
clutter_layout_manager_set_container (priv->layout_manager, NULL);
|
||||
g_clear_object (&priv->layout_manager);
|
||||
}
|
||||
@@ -17985,9 +18221,10 @@ clutter_actor_set_layout_manager (ClutterActor *self,
|
||||
g_object_ref_sink (priv->layout_manager);
|
||||
clutter_layout_manager_set_container (priv->layout_manager,
|
||||
CLUTTER_CONTAINER (self));
|
||||
g_signal_connect (priv->layout_manager, "layout-changed",
|
||||
G_CALLBACK (on_layout_manager_changed),
|
||||
self);
|
||||
priv->layout_changed_id =
|
||||
g_signal_connect (priv->layout_manager, "layout-changed",
|
||||
G_CALLBACK (on_layout_manager_changed),
|
||||
self);
|
||||
}
|
||||
|
||||
clutter_actor_queue_relayout (self);
|
||||
@@ -19111,7 +19348,8 @@ should_skip_implicit_transition (ClutterActor *self,
|
||||
* skip all transitions on the :allocation, to avoid actors "flying in"
|
||||
* into their new position and size
|
||||
*/
|
||||
if (pspec == obj_props[PROP_ALLOCATION] && priv->needs_allocation)
|
||||
if (pspec == obj_props[PROP_ALLOCATION] &&
|
||||
!clutter_actor_box_is_initialized (&priv->allocation))
|
||||
return TRUE;
|
||||
|
||||
/* if the actor is not mapped and is not part of a branch of the scene
|
||||
|
@@ -919,6 +919,9 @@ void clutter_actor_pick_box (ClutterActor *self,
|
||||
ClutterPickContext *pick_context,
|
||||
const ClutterActorBox *box);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GList * clutter_actor_peek_stage_views (ClutterActor *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_ACTOR_H__ */
|
||||
|
@@ -58,6 +58,7 @@ struct _ClutterAlignConstraint
|
||||
ClutterActor *actor;
|
||||
ClutterActor *source;
|
||||
ClutterAlignAxis align_axis;
|
||||
graphene_point_t pivot;
|
||||
gfloat factor;
|
||||
};
|
||||
|
||||
@@ -72,6 +73,7 @@ enum
|
||||
|
||||
PROP_SOURCE,
|
||||
PROP_ALIGN_AXIS,
|
||||
PROP_PIVOT_POINT,
|
||||
PROP_FACTOR,
|
||||
|
||||
PROP_LAST
|
||||
@@ -84,12 +86,11 @@ G_DEFINE_TYPE (ClutterAlignConstraint,
|
||||
CLUTTER_TYPE_CONSTRAINT);
|
||||
|
||||
static void
|
||||
source_position_changed (ClutterActor *actor,
|
||||
GParamSpec *pspec,
|
||||
ClutterAlignConstraint *align)
|
||||
source_queue_relayout (ClutterActor *actor,
|
||||
ClutterAlignConstraint *align)
|
||||
{
|
||||
if (align->actor != NULL)
|
||||
clutter_actor_queue_relayout (align->actor);
|
||||
_clutter_actor_queue_only_relayout (align->actor);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -134,35 +135,41 @@ clutter_align_constraint_update_allocation (ClutterConstraint *constraint,
|
||||
ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (constraint);
|
||||
gfloat source_width, source_height;
|
||||
gfloat actor_width, actor_height;
|
||||
gfloat source_x, source_y;
|
||||
gfloat offset_x_start, offset_y_start;
|
||||
gfloat pivot_x, pivot_y;
|
||||
|
||||
if (align->source == NULL)
|
||||
return;
|
||||
|
||||
clutter_actor_box_get_size (allocation, &actor_width, &actor_height);
|
||||
|
||||
clutter_actor_get_position (align->source, &source_x, &source_y);
|
||||
clutter_actor_get_size (align->source, &source_width, &source_height);
|
||||
|
||||
pivot_x = align->pivot.x == -1.f
|
||||
? align->factor
|
||||
: align->pivot.x;
|
||||
pivot_y = align->pivot.y == -1.f
|
||||
? align->factor
|
||||
: align->pivot.y;
|
||||
|
||||
offset_x_start = pivot_x * -actor_width;
|
||||
offset_y_start = pivot_y * -actor_height;
|
||||
|
||||
switch (align->align_axis)
|
||||
{
|
||||
case CLUTTER_ALIGN_X_AXIS:
|
||||
allocation->x1 = ((source_width - actor_width) * align->factor)
|
||||
+ source_x;
|
||||
allocation->x1 += offset_x_start + (source_width * align->factor);
|
||||
allocation->x2 = allocation->x1 + actor_width;
|
||||
break;
|
||||
|
||||
case CLUTTER_ALIGN_Y_AXIS:
|
||||
allocation->y1 = ((source_height - actor_height) * align->factor)
|
||||
+ source_y;
|
||||
allocation->y1 += offset_y_start + (source_height * align->factor);
|
||||
allocation->y2 = allocation->y1 + actor_height;
|
||||
break;
|
||||
|
||||
case CLUTTER_ALIGN_BOTH:
|
||||
allocation->x1 = ((source_width - actor_width) * align->factor)
|
||||
+ source_x;
|
||||
allocation->y1 = ((source_height - actor_height) * align->factor)
|
||||
+ source_y;
|
||||
allocation->x1 += offset_x_start + (source_width * align->factor);
|
||||
allocation->y1 += offset_y_start + (source_height * align->factor);
|
||||
allocation->x2 = allocation->x1 + actor_width;
|
||||
allocation->y2 = allocation->y1 + actor_height;
|
||||
break;
|
||||
@@ -186,7 +193,7 @@ clutter_align_constraint_dispose (GObject *gobject)
|
||||
G_CALLBACK (source_destroyed),
|
||||
align);
|
||||
g_signal_handlers_disconnect_by_func (align->source,
|
||||
G_CALLBACK (source_position_changed),
|
||||
G_CALLBACK (source_queue_relayout),
|
||||
align);
|
||||
align->source = NULL;
|
||||
}
|
||||
@@ -212,6 +219,10 @@ clutter_align_constraint_set_property (GObject *gobject,
|
||||
clutter_align_constraint_set_align_axis (align, g_value_get_enum (value));
|
||||
break;
|
||||
|
||||
case PROP_PIVOT_POINT:
|
||||
clutter_align_constraint_set_pivot_point (align, g_value_get_boxed (value));
|
||||
break;
|
||||
|
||||
case PROP_FACTOR:
|
||||
clutter_align_constraint_set_factor (align, g_value_get_float (value));
|
||||
break;
|
||||
@@ -240,6 +251,16 @@ clutter_align_constraint_get_property (GObject *gobject,
|
||||
g_value_set_enum (value, align->align_axis);
|
||||
break;
|
||||
|
||||
case PROP_PIVOT_POINT:
|
||||
{
|
||||
graphene_point_t point;
|
||||
|
||||
clutter_align_constraint_get_pivot_point (align, &point);
|
||||
|
||||
g_value_set_boxed (value, &point);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_FACTOR:
|
||||
g_value_set_float (value, align->factor);
|
||||
break;
|
||||
@@ -293,6 +314,30 @@ clutter_align_constraint_class_init (ClutterAlignConstraintClass *klass)
|
||||
CLUTTER_ALIGN_X_AXIS,
|
||||
CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT);
|
||||
|
||||
/**
|
||||
* ClutterAlignConstraint:pivot-point:
|
||||
*
|
||||
* The pivot point used by the constraint. The pivot point is the
|
||||
* point in the constraint actor around which the aligning is applied,
|
||||
* with (0, 0) being the top left corner of the actor and (1, 1) the
|
||||
* bottom right corner of the actor.
|
||||
*
|
||||
* For example, setting the pivot point to (0.5, 0.5) and using a factor
|
||||
* of 1 for both axes will align the actors horizontal and vertical
|
||||
* center point with the bottom right corner of the source actor.
|
||||
*
|
||||
* By default, the pivot point is set to (-1, -1), which means it's not
|
||||
* used and the constrained actor will be aligned to always stay inside
|
||||
* the source actor.
|
||||
*/
|
||||
obj_props[PROP_PIVOT_POINT] =
|
||||
g_param_spec_boxed ("pivot-point",
|
||||
P_("Pivot point"),
|
||||
P_("The pivot point"),
|
||||
GRAPHENE_TYPE_POINT,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClutterAlignConstraint:factor:
|
||||
*
|
||||
@@ -325,6 +370,8 @@ clutter_align_constraint_init (ClutterAlignConstraint *self)
|
||||
self->actor = NULL;
|
||||
self->source = NULL;
|
||||
self->align_axis = CLUTTER_ALIGN_X_AXIS;
|
||||
self->pivot.x = -1.f;
|
||||
self->pivot.y = -1.f;
|
||||
self->factor = 0.0f;
|
||||
}
|
||||
|
||||
@@ -402,15 +449,15 @@ clutter_align_constraint_set_source (ClutterAlignConstraint *align,
|
||||
G_CALLBACK (source_destroyed),
|
||||
align);
|
||||
g_signal_handlers_disconnect_by_func (old_source,
|
||||
G_CALLBACK (source_position_changed),
|
||||
G_CALLBACK (source_queue_relayout),
|
||||
align);
|
||||
}
|
||||
|
||||
align->source = source;
|
||||
if (align->source != NULL)
|
||||
{
|
||||
g_signal_connect (align->source, "notify::allocation",
|
||||
G_CALLBACK (source_position_changed),
|
||||
g_signal_connect (align->source, "queue-relayout",
|
||||
G_CALLBACK (source_queue_relayout),
|
||||
align);
|
||||
g_signal_connect (align->source, "destroy",
|
||||
G_CALLBACK (source_destroyed),
|
||||
@@ -487,6 +534,60 @@ clutter_align_constraint_get_align_axis (ClutterAlignConstraint *align)
|
||||
return align->align_axis;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_align_constraint_set_pivot_point:
|
||||
* @align: a #ClutterAlignConstraint
|
||||
* @pivot_point: A #GraphenePoint
|
||||
*
|
||||
* Sets the pivot point used by the constraint, the pivot point is the
|
||||
* point in the constraint actor around which the aligning is applied,
|
||||
* with (0, 0) being the top left corner of the actor and (1, 1) the
|
||||
* bottom right corner of the actor.
|
||||
*
|
||||
* If -1 is used, the pivot point is unset and the constrained actor
|
||||
* will be aligned to always stay inside the source actor.
|
||||
*/
|
||||
void
|
||||
clutter_align_constraint_set_pivot_point (ClutterAlignConstraint *align,
|
||||
const graphene_point_t *pivot_point)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align));
|
||||
g_return_if_fail (pivot_point != NULL);
|
||||
g_return_if_fail (pivot_point->x == -1.f ||
|
||||
(pivot_point->x >= 0.f && pivot_point->x <= 1.f));
|
||||
g_return_if_fail (pivot_point->y == -1.f ||
|
||||
(pivot_point->y >= 0.f && pivot_point->y <= 1.f));
|
||||
|
||||
if (graphene_point_equal (&align->pivot, pivot_point))
|
||||
return;
|
||||
|
||||
align->pivot = *pivot_point;
|
||||
|
||||
if (align->actor != NULL)
|
||||
clutter_actor_queue_relayout (align->actor);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (align), obj_props[PROP_PIVOT_POINT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_align_constraint_get_pivot_point
|
||||
* @align: a #ClutterAlignConstraint
|
||||
* @pivot_point: (out caller-allocates): return location for a #GraphenePoint
|
||||
*
|
||||
* Gets the pivot point used by the constraint set with
|
||||
* clutter_align_constraint_set_pivot_point(). If no custom pivot
|
||||
* point is set, -1 is set.
|
||||
*/
|
||||
void
|
||||
clutter_align_constraint_get_pivot_point (ClutterAlignConstraint *align,
|
||||
graphene_point_t *pivot_point)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align));
|
||||
g_return_if_fail (pivot_point != NULL);
|
||||
|
||||
*pivot_point = align->pivot;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_align_constraint_set_factor:
|
||||
* @align: a #ClutterAlignConstraint
|
||||
|
@@ -67,6 +67,12 @@ void clutter_align_constraint_set_align_axis (ClutterAlignConstrai
|
||||
CLUTTER_EXPORT
|
||||
ClutterAlignAxis clutter_align_constraint_get_align_axis (ClutterAlignConstraint *align);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_align_constraint_set_pivot_point (ClutterAlignConstraint *align,
|
||||
const graphene_point_t *pivot_point);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_align_constraint_get_pivot_point (ClutterAlignConstraint *align,
|
||||
graphene_point_t *pivot_point);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_align_constraint_set_factor (ClutterAlignConstraint *align,
|
||||
gfloat factor);
|
||||
CLUTTER_EXPORT
|
||||
|
@@ -165,6 +165,9 @@ clutter_bind_constraint_update_preferred_size (ClutterConstraint *constraint,
|
||||
bind->coordinate == CLUTTER_BIND_ALL))
|
||||
return;
|
||||
|
||||
if (clutter_actor_contains (bind->source, actor))
|
||||
return;
|
||||
|
||||
switch (direction)
|
||||
{
|
||||
case CLUTTER_ORIENTATION_HORIZONTAL:
|
||||
|
@@ -52,6 +52,8 @@
|
||||
struct _ClutterClonePrivate
|
||||
{
|
||||
ClutterActor *clone_source;
|
||||
float x_scale, y_scale;
|
||||
|
||||
gulong source_destroy_id;
|
||||
};
|
||||
|
||||
@@ -122,8 +124,6 @@ static void
|
||||
clutter_clone_apply_transform (ClutterActor *self, CoglMatrix *matrix)
|
||||
{
|
||||
ClutterClonePrivate *priv = CLUTTER_CLONE (self)->priv;
|
||||
ClutterActorBox box, source_box;
|
||||
gfloat x_scale, y_scale;
|
||||
|
||||
/* First chain up and apply all the standard ClutterActor
|
||||
* transformations... */
|
||||
@@ -134,21 +134,7 @@ clutter_clone_apply_transform (ClutterActor *self, CoglMatrix *matrix)
|
||||
if (priv->clone_source == NULL)
|
||||
return;
|
||||
|
||||
/* get our allocated size */
|
||||
clutter_actor_get_allocation_box (self, &box);
|
||||
|
||||
/* and get the allocated size of the source */
|
||||
clutter_actor_get_allocation_box (priv->clone_source, &source_box);
|
||||
|
||||
/* We need to scale what the clone-source actor paints to fill our own
|
||||
* allocation...
|
||||
*/
|
||||
x_scale = clutter_actor_box_get_width (&box)
|
||||
/ clutter_actor_box_get_width (&source_box);
|
||||
y_scale = clutter_actor_box_get_height (&box)
|
||||
/ clutter_actor_box_get_height (&source_box);
|
||||
|
||||
cogl_matrix_scale (matrix, x_scale, y_scale, x_scale);
|
||||
cogl_matrix_scale (matrix, priv->x_scale, priv->y_scale, 1.f);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -244,6 +230,8 @@ clutter_clone_allocate (ClutterActor *self,
|
||||
{
|
||||
ClutterClonePrivate *priv = CLUTTER_CLONE (self)->priv;
|
||||
ClutterActorClass *parent_class;
|
||||
ClutterActorBox source_box;
|
||||
float x_scale, y_scale;
|
||||
|
||||
/* chain up */
|
||||
parent_class = CLUTTER_ACTOR_CLASS (clutter_clone_parent_class);
|
||||
@@ -259,6 +247,23 @@ clutter_clone_allocate (ClutterActor *self,
|
||||
!clutter_actor_has_allocation (priv->clone_source))
|
||||
clutter_actor_allocate_preferred_size (priv->clone_source);
|
||||
|
||||
clutter_actor_get_allocation_box (priv->clone_source, &source_box);
|
||||
|
||||
/* We need to scale what the clone-source actor paints to fill our own
|
||||
* allocation...
|
||||
*/
|
||||
x_scale = clutter_actor_box_get_width (box)
|
||||
/ clutter_actor_box_get_width (&source_box);
|
||||
y_scale = clutter_actor_box_get_height (box)
|
||||
/ clutter_actor_box_get_height (&source_box);
|
||||
|
||||
if (!G_APPROX_VALUE (priv->x_scale, x_scale, FLT_EPSILON) ||
|
||||
!G_APPROX_VALUE (priv->y_scale, y_scale, FLT_EPSILON))
|
||||
{
|
||||
priv->x_scale = x_scale;
|
||||
priv->y_scale = y_scale;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* XXX - this is wrong: ClutterClone cannot clone unparented
|
||||
* actors, as it will break all invariants
|
||||
@@ -364,6 +369,9 @@ static void
|
||||
clutter_clone_init (ClutterClone *self)
|
||||
{
|
||||
self->priv = clutter_clone_get_instance_private (self);
|
||||
|
||||
self->priv->x_scale = 1.f;
|
||||
self->priv->y_scale = 1.f;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1317,8 +1317,6 @@ typedef enum
|
||||
* painting the stages
|
||||
* @CLUTTER_REPAINT_FLAGS_POST_PAINT: Run the repaint function after
|
||||
* painting the stages
|
||||
* @CLUTTER_REPAINT_FLAGS_QUEUE_REDRAW_ON_ADD: Ensure that a new frame
|
||||
* is queued after adding the repaint function
|
||||
*
|
||||
* Flags to pass to clutter_threads_add_repaint_func_full().
|
||||
*
|
||||
@@ -1328,7 +1326,6 @@ typedef enum
|
||||
{
|
||||
CLUTTER_REPAINT_FLAGS_PRE_PAINT = 1 << 0,
|
||||
CLUTTER_REPAINT_FLAGS_POST_PAINT = 1 << 1,
|
||||
CLUTTER_REPAINT_FLAGS_QUEUE_REDRAW_ON_ADD = 1 << 2
|
||||
} ClutterRepaintFlags;
|
||||
|
||||
/**
|
||||
|
@@ -692,20 +692,6 @@ _clutter_input_device_free_touch_info (gpointer data)
|
||||
g_slice_free (ClutterTouchInfo, data);
|
||||
}
|
||||
|
||||
static ClutterActor *
|
||||
_clutter_input_device_get_actor (ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence)
|
||||
{
|
||||
ClutterTouchInfo *info;
|
||||
|
||||
if (sequence == NULL)
|
||||
return device->cursor_actor;
|
||||
|
||||
info = g_hash_table_lookup (device->touch_sequences_info, sequence);
|
||||
|
||||
return info->actor;
|
||||
}
|
||||
|
||||
static void
|
||||
_clutter_input_device_associate_actor (ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence,
|
||||
@@ -815,7 +801,7 @@ _clutter_input_device_set_actor (ClutterInputDevice *device,
|
||||
ClutterActor *actor,
|
||||
gboolean emit_crossing)
|
||||
{
|
||||
ClutterActor *old_actor = _clutter_input_device_get_actor (device, sequence);
|
||||
ClutterActor *old_actor = clutter_input_device_get_actor (device, sequence);
|
||||
|
||||
if (old_actor == actor)
|
||||
return;
|
||||
@@ -850,7 +836,7 @@ _clutter_input_device_set_actor (ClutterInputDevice *device,
|
||||
}
|
||||
|
||||
/* processing the event might have destroyed the actor */
|
||||
tmp_old_actor = _clutter_input_device_get_actor (device, sequence);
|
||||
tmp_old_actor = clutter_input_device_get_actor (device, sequence);
|
||||
_clutter_input_device_unassociate_actor (device,
|
||||
old_actor,
|
||||
tmp_old_actor == NULL);
|
||||
@@ -1054,7 +1040,7 @@ clutter_input_device_update (ClutterInputDevice *device,
|
||||
|
||||
clutter_input_device_get_coords (device, sequence, &point);
|
||||
|
||||
old_cursor_actor = _clutter_input_device_get_actor (device, sequence);
|
||||
old_cursor_actor = clutter_input_device_get_actor (device, sequence);
|
||||
new_cursor_actor =
|
||||
_clutter_stage_do_pick (stage, point.x, point.y, CLUTTER_PICK_REACTIVE);
|
||||
|
||||
@@ -1085,22 +1071,33 @@ clutter_input_device_update (ClutterInputDevice *device,
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_input_device_get_pointer_actor:
|
||||
* @device: a #ClutterInputDevice of type %CLUTTER_POINTER_DEVICE
|
||||
* clutter_input_device_get_actor:
|
||||
* @device: a #ClutterInputDevice
|
||||
* @sequence: (allow-none): an optional #ClutterEventSequence
|
||||
*
|
||||
* Retrieves the #ClutterActor underneath the pointer of @device
|
||||
* Retrieves the #ClutterActor underneath the pointer or touchpoint
|
||||
* of @device and @sequence.
|
||||
*
|
||||
* Return value: (transfer none): a pointer to the #ClutterActor or %NULL
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
ClutterActor *
|
||||
clutter_input_device_get_pointer_actor (ClutterInputDevice *device)
|
||||
clutter_input_device_get_actor (ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL);
|
||||
g_return_val_if_fail (device->device_type == CLUTTER_POINTER_DEVICE, NULL);
|
||||
ClutterTouchInfo *info;
|
||||
|
||||
return device->cursor_actor;
|
||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL);
|
||||
|
||||
if (sequence == NULL)
|
||||
return device->cursor_actor;
|
||||
|
||||
info = g_hash_table_lookup (device->touch_sequences_info, sequence);
|
||||
|
||||
g_return_val_if_fail (info != NULL, NULL);
|
||||
|
||||
return info->actor;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -92,7 +92,8 @@ gboolean clutter_input_device_get_coords (ClutterInputDevi
|
||||
CLUTTER_EXPORT
|
||||
ClutterModifierType clutter_input_device_get_modifier_state (ClutterInputDevice *device);
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor * clutter_input_device_get_pointer_actor (ClutterInputDevice *device);
|
||||
ClutterActor * clutter_input_device_get_actor (ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence);
|
||||
CLUTTER_EXPORT
|
||||
ClutterStage * clutter_input_device_get_pointer_stage (ClutterInputDevice *device);
|
||||
CLUTTER_EXPORT
|
||||
|
@@ -1653,6 +1653,8 @@ static inline void
|
||||
emit_keyboard_event (ClutterEvent *event,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
cally_snoop_key_event ((ClutterKeyEvent *) event);
|
||||
|
||||
if (_clutter_event_process_filters (event))
|
||||
return;
|
||||
|
||||
@@ -2049,7 +2051,8 @@ _clutter_process_event_details (ClutterActor *stage,
|
||||
|
||||
emit_touch_event (event, device);
|
||||
|
||||
if (event->type == CLUTTER_TOUCH_END)
|
||||
if (event->type == CLUTTER_TOUCH_END ||
|
||||
event->type == CLUTTER_TOUCH_CANCEL)
|
||||
_clutter_input_device_remove_event_sequence (device, event);
|
||||
|
||||
break;
|
||||
@@ -2084,7 +2087,8 @@ _clutter_process_event_details (ClutterActor *stage,
|
||||
|
||||
emit_touch_event (event, device);
|
||||
|
||||
if (event->type == CLUTTER_TOUCH_END)
|
||||
if (event->type == CLUTTER_TOUCH_END ||
|
||||
event->type == CLUTTER_TOUCH_CANCEL)
|
||||
_clutter_input_device_remove_event_sequence (device, event);
|
||||
|
||||
break;
|
||||
@@ -2392,8 +2396,7 @@ clutter_threads_add_repaint_func_full (ClutterRepaintFlags flags,
|
||||
|
||||
repaint_func->id = context->last_repaint_id++;
|
||||
|
||||
/* mask out QUEUE_REDRAW_ON_ADD, since we're going to consume it */
|
||||
repaint_func->flags = flags & ~CLUTTER_REPAINT_FLAGS_QUEUE_REDRAW_ON_ADD;
|
||||
repaint_func->flags = flags;
|
||||
repaint_func->func = func;
|
||||
repaint_func->data = data;
|
||||
repaint_func->notify = notify;
|
||||
@@ -2403,13 +2406,6 @@ clutter_threads_add_repaint_func_full (ClutterRepaintFlags flags,
|
||||
|
||||
_clutter_context_unlock ();
|
||||
|
||||
if ((flags & CLUTTER_REPAINT_FLAGS_QUEUE_REDRAW_ON_ADD) != 0)
|
||||
{
|
||||
ClutterMasterClock *master_clock = _clutter_master_clock_get_default ();
|
||||
|
||||
_clutter_master_clock_ensure_next_iteration (master_clock);
|
||||
}
|
||||
|
||||
return repaint_func->id;
|
||||
}
|
||||
|
||||
|
@@ -75,7 +75,7 @@ CLUTTER_EXPORT
|
||||
void clutter_stage_thaw_updates (ClutterStage *stage);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_stage_update_resource_scales (ClutterStage *stage);
|
||||
void clutter_stage_clear_stage_views (ClutterStage *stage);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_stage_view_assign_next_scanout (ClutterStageView *stage_view,
|
||||
|
@@ -136,7 +136,8 @@ enum
|
||||
|
||||
static guint pan_signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (ClutterPanAction, clutter_pan_action, CLUTTER_TYPE_GESTURE_ACTION)
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (ClutterPanAction, clutter_pan_action,
|
||||
CLUTTER_TYPE_GESTURE_ACTION)
|
||||
|
||||
static void
|
||||
emit_pan (ClutterPanAction *self,
|
||||
@@ -156,14 +157,18 @@ emit_pan (ClutterPanAction *self,
|
||||
gfloat scroll_threshold = G_PI_4/2;
|
||||
gfloat drag_angle;
|
||||
|
||||
clutter_gesture_action_get_motion_delta (CLUTTER_GESTURE_ACTION (self), 0, &delta_x, &delta_y);
|
||||
clutter_gesture_action_get_motion_delta (CLUTTER_GESTURE_ACTION (self),
|
||||
0,
|
||||
&delta_x,
|
||||
&delta_y);
|
||||
|
||||
if (delta_x != 0.0f)
|
||||
drag_angle = atanf (delta_y / delta_x);
|
||||
else
|
||||
drag_angle = G_PI_2;
|
||||
|
||||
if ((drag_angle > -scroll_threshold) && (drag_angle < scroll_threshold))
|
||||
if ((drag_angle > -scroll_threshold) &&
|
||||
(drag_angle < scroll_threshold))
|
||||
priv->pin_state = SCROLL_PINNED_HORIZONTAL;
|
||||
else if ((drag_angle > (G_PI_2 - scroll_threshold)) ||
|
||||
(drag_angle < -(G_PI_2 - scroll_threshold)))
|
||||
@@ -282,7 +287,10 @@ gesture_end (ClutterGestureAction *gesture,
|
||||
gfloat tau;
|
||||
gint duration;
|
||||
|
||||
clutter_gesture_action_get_release_coords (CLUTTER_GESTURE_ACTION (self), 0, &priv->release_x, &priv->release_y);
|
||||
clutter_gesture_action_get_release_coords (CLUTTER_GESTURE_ACTION (self),
|
||||
0,
|
||||
&priv->release_x,
|
||||
&priv->release_y);
|
||||
|
||||
if (!priv->should_interpolate)
|
||||
{
|
||||
@@ -293,7 +301,9 @@ gesture_end (ClutterGestureAction *gesture,
|
||||
priv->state = PAN_STATE_INTERPOLATING;
|
||||
|
||||
clutter_gesture_action_get_motion_delta (gesture, 0, &delta_x, &delta_y);
|
||||
velocity = clutter_gesture_action_get_velocity (gesture, 0, &velocity_x, &velocity_y);
|
||||
velocity = clutter_gesture_action_get_velocity (gesture, 0,
|
||||
&velocity_x,
|
||||
&velocity_y);
|
||||
|
||||
/* Exponential timing constant v(t) = v(0) * exp(-t/tau)
|
||||
* tau = 1000ms / (frame_per_second * - ln(decay_per_frame))
|
||||
@@ -304,17 +314,22 @@ gesture_end (ClutterGestureAction *gesture,
|
||||
/* See where the decreasing velocity reaches $min_velocity px/ms
|
||||
* v(t) = v(0) * exp(-t/tau) = min_velocity
|
||||
* t = - tau * ln( min_velocity / |v(0)|) */
|
||||
duration = - tau * logf (min_velocity / (ABS (velocity) * priv->acceleration_factor));
|
||||
duration = - tau * logf (min_velocity / (ABS (velocity) *
|
||||
priv->acceleration_factor));
|
||||
|
||||
/* Target point: x(t) = v(0) * tau * [1 - exp(-t/tau)] */
|
||||
priv->target_x = velocity_x * priv->acceleration_factor * tau * (1 - exp ((float)-duration / tau));
|
||||
priv->target_y = velocity_y * priv->acceleration_factor * tau * (1 - exp ((float)-duration / tau));
|
||||
priv->target_x = (velocity_x * priv->acceleration_factor * tau *
|
||||
(1 - exp ((float)-duration / tau)));
|
||||
priv->target_y = (velocity_y * priv->acceleration_factor * tau *
|
||||
(1 - exp ((float)-duration / tau)));
|
||||
|
||||
if (ABS (velocity) * priv->acceleration_factor > min_velocity && duration > FLOAT_EPSILON)
|
||||
if (ABS (velocity) * priv->acceleration_factor > min_velocity &&
|
||||
duration > FLOAT_EPSILON)
|
||||
{
|
||||
priv->interpolated_x = priv->interpolated_y = 0.0f;
|
||||
priv->deceleration_timeline = clutter_timeline_new (duration);
|
||||
clutter_timeline_set_progress_mode (priv->deceleration_timeline, CLUTTER_EASE_OUT_EXPO);
|
||||
clutter_timeline_set_progress_mode (priv->deceleration_timeline,
|
||||
CLUTTER_EASE_OUT_EXPO);
|
||||
|
||||
g_signal_connect (priv->deceleration_timeline, "new_frame",
|
||||
G_CALLBACK (on_deceleration_new_frame), self);
|
||||
@@ -367,7 +382,8 @@ clutter_pan_action_set_property (GObject *gobject,
|
||||
break;
|
||||
|
||||
case PROP_ACCELERATION_FACTOR :
|
||||
clutter_pan_action_set_acceleration_factor (self, g_value_get_double (value));
|
||||
clutter_pan_action_set_acceleration_factor (self,
|
||||
g_value_get_double (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -411,9 +427,11 @@ static void
|
||||
clutter_pan_action_constructed (GObject *gobject)
|
||||
{
|
||||
ClutterGestureAction *gesture;
|
||||
ClutterGestureTriggerEdge edge;
|
||||
|
||||
gesture = CLUTTER_GESTURE_ACTION (gobject);
|
||||
clutter_gesture_action_set_threshold_trigger_edge (gesture, CLUTTER_GESTURE_TRIGGER_EDGE_AFTER);
|
||||
edge = CLUTTER_GESTURE_TRIGGER_EDGE_AFTER;
|
||||
clutter_gesture_action_set_threshold_trigger_edge (gesture, edge);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -442,7 +460,8 @@ clutter_pan_action_set_actor (ClutterActorMeta *meta,
|
||||
g_clear_object (&priv->deceleration_timeline);
|
||||
}
|
||||
|
||||
CLUTTER_ACTOR_META_CLASS (clutter_pan_action_parent_class)->set_actor (meta, actor);
|
||||
CLUTTER_ACTOR_META_CLASS (clutter_pan_action_parent_class)->set_actor (meta,
|
||||
actor);
|
||||
}
|
||||
|
||||
|
||||
@@ -880,7 +899,9 @@ clutter_pan_action_get_constrained_motion_delta (ClutterPanAction *self,
|
||||
|
||||
priv = self->priv;
|
||||
|
||||
distance = clutter_pan_action_get_motion_delta (self, point, &delta_x, &delta_y);
|
||||
distance = clutter_pan_action_get_motion_delta (self, point,
|
||||
&delta_x,
|
||||
&delta_y);
|
||||
|
||||
switch (priv->pan_axis)
|
||||
{
|
||||
|
@@ -1523,7 +1523,7 @@ clutter_script_construct_parameters (ClutterScript *script,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(pspec->flags & G_PARAM_CONSTRUCT_ONLY))
|
||||
if (!(pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY)))
|
||||
{
|
||||
unparsed = g_list_prepend (unparsed, pinfo);
|
||||
continue;
|
||||
|
@@ -354,6 +354,17 @@ clutter_seat_get_keyboard (ClutterSeat *seat)
|
||||
return CLUTTER_SEAT_GET_CLASS (seat)->get_keyboard (seat);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_seat_peek_devices: (skip)
|
||||
**/
|
||||
const GList *
|
||||
clutter_seat_peek_devices (ClutterSeat *seat)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_SEAT (seat), NULL);
|
||||
|
||||
return CLUTTER_SEAT_GET_CLASS (seat)->peek_devices (seat);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_seat_list_devices:
|
||||
* @seat: a #ClutterSeat
|
||||
@@ -370,7 +381,7 @@ clutter_seat_list_devices (ClutterSeat *seat)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_SEAT (seat), NULL);
|
||||
|
||||
return CLUTTER_SEAT_GET_CLASS (seat)->list_devices (seat);
|
||||
return g_list_copy ((GList *)clutter_seat_peek_devices (seat));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -634,8 +645,8 @@ clutter_seat_create_virtual_device (ClutterSeat *seat,
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_seat_supported_virtual_device_types: (skip)
|
||||
*/
|
||||
* clutter_seat_get_supported_virtual_device_types: (skip)
|
||||
**/
|
||||
ClutterVirtualDeviceType
|
||||
clutter_seat_get_supported_virtual_device_types (ClutterSeat *seat)
|
||||
{
|
||||
|
@@ -96,7 +96,7 @@ struct _ClutterSeatClass
|
||||
ClutterInputDevice * (* get_pointer) (ClutterSeat *seat);
|
||||
ClutterInputDevice * (* get_keyboard) (ClutterSeat *seat);
|
||||
|
||||
GList * (* list_devices) (ClutterSeat *seat);
|
||||
const GList * (* peek_devices) (ClutterSeat *seat);
|
||||
|
||||
void (* bell_notify) (ClutterSeat *seat);
|
||||
|
||||
@@ -133,6 +133,7 @@ CLUTTER_EXPORT
|
||||
ClutterInputDevice * clutter_seat_get_keyboard (ClutterSeat *seat);
|
||||
CLUTTER_EXPORT
|
||||
GList * clutter_seat_list_devices (ClutterSeat *seat);
|
||||
const GList * clutter_seat_peek_devices (ClutterSeat *seat);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_seat_bell_notify (ClutterSeat *seat);
|
||||
|
||||
|
@@ -125,9 +125,6 @@ gboolean _clutter_stage_update_state (ClutterStage *stag
|
||||
|
||||
void _clutter_stage_set_scale_factor (ClutterStage *stage,
|
||||
int factor);
|
||||
gboolean _clutter_stage_get_max_view_scale_factor_for_rect (ClutterStage *stage,
|
||||
graphene_rect_t *rect,
|
||||
float *view_scale);
|
||||
|
||||
void _clutter_stage_presented (ClutterStage *stage,
|
||||
CoglFrameEvent frame_event,
|
||||
@@ -136,6 +133,9 @@ void _clutter_stage_presented (ClutterStage *stag
|
||||
void clutter_stage_queue_actor_relayout (ClutterStage *stage,
|
||||
ClutterActor *actor);
|
||||
|
||||
GList * clutter_stage_get_views_for_rect (ClutterStage *stage,
|
||||
const graphene_rect_t *rect);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_STAGE_PRIVATE_H__ */
|
||||
|
@@ -45,7 +45,7 @@
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <cairo.h>
|
||||
#include <cairo-gobject.h>
|
||||
|
||||
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
|
||||
#define CLUTTER_ENABLE_EXPERIMENTAL_API
|
||||
@@ -119,8 +119,7 @@ struct _ClutterStagePrivate
|
||||
|
||||
ClutterPlane current_clip_planes[4];
|
||||
|
||||
GHashTable *pending_relayouts;
|
||||
unsigned int pending_relayouts_version;
|
||||
GSList *pending_relayouts;
|
||||
GList *pending_queue_redraws;
|
||||
|
||||
gint sync_delay;
|
||||
@@ -1071,6 +1070,7 @@ clutter_stage_hide (ClutterActor *self)
|
||||
ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv;
|
||||
|
||||
g_assert (priv->impl != NULL);
|
||||
_clutter_stage_clear_pick_stack (CLUTTER_STAGE (self));
|
||||
_clutter_stage_window_hide (priv->impl);
|
||||
|
||||
CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->hide (self);
|
||||
@@ -1129,7 +1129,6 @@ _clutter_stage_queue_event (ClutterStage *stage,
|
||||
event->type != CLUTTER_PROXIMITY_IN &&
|
||||
event->type != CLUTTER_PROXIMITY_OUT)
|
||||
{
|
||||
ClutterModifierType event_state = clutter_event_get_state (event);
|
||||
ClutterEventSequence *sequence = clutter_event_get_event_sequence (event);
|
||||
guint32 event_time = clutter_event_get_time (event);
|
||||
gfloat event_x, event_y;
|
||||
@@ -1137,7 +1136,6 @@ _clutter_stage_queue_event (ClutterStage *stage,
|
||||
clutter_event_get_coords (event, &event_x, &event_y);
|
||||
|
||||
_clutter_input_device_set_coords (device, sequence, event_x, event_y, stage);
|
||||
_clutter_input_device_set_state (device, event_state);
|
||||
_clutter_input_device_set_time (device, event_time);
|
||||
}
|
||||
|
||||
@@ -1294,7 +1292,7 @@ _clutter_stage_needs_update (ClutterStage *stage)
|
||||
|
||||
return (priv->redraw_pending ||
|
||||
priv->needs_update ||
|
||||
g_hash_table_size (priv->pending_relayouts) > 0);
|
||||
priv->pending_relayouts != NULL);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1303,11 +1301,11 @@ clutter_stage_queue_actor_relayout (ClutterStage *stage,
|
||||
{
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
|
||||
if (g_hash_table_size (priv->pending_relayouts) == 0)
|
||||
if (priv->pending_relayouts == NULL)
|
||||
clutter_stage_schedule_update (stage);
|
||||
|
||||
g_hash_table_add (priv->pending_relayouts, g_object_ref (actor));
|
||||
priv->pending_relayouts_version++;
|
||||
priv->pending_relayouts = g_slist_prepend (priv->pending_relayouts,
|
||||
g_object_ref (actor));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1315,24 +1313,20 @@ _clutter_stage_maybe_relayout (ClutterActor *actor)
|
||||
{
|
||||
ClutterStage *stage = CLUTTER_STAGE (actor);
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
GHashTableIter iter;
|
||||
gpointer key;
|
||||
g_autoptr (GSList) stolen_list = NULL;
|
||||
GSList *l;
|
||||
int count = 0;
|
||||
|
||||
/* No work to do? Avoid the extraneous debug log messages too. */
|
||||
if (g_hash_table_size (priv->pending_relayouts) == 0)
|
||||
if (priv->pending_relayouts == NULL)
|
||||
return;
|
||||
|
||||
CLUTTER_NOTE (ACTOR, ">>> Recomputing layout");
|
||||
|
||||
g_hash_table_iter_init (&iter, priv->pending_relayouts);
|
||||
while (g_hash_table_iter_next (&iter, &key, NULL))
|
||||
stolen_list = g_steal_pointer (&priv->pending_relayouts);
|
||||
for (l = stolen_list; l; l = l->next)
|
||||
{
|
||||
g_autoptr (ClutterActor) queued_actor = key;
|
||||
unsigned int old_version;
|
||||
|
||||
g_hash_table_iter_steal (&iter);
|
||||
priv->pending_relayouts_version++;
|
||||
g_autoptr (ClutterActor) queued_actor = l->data;
|
||||
|
||||
if (CLUTTER_ACTOR_IN_RELAYOUT (queued_actor)) /* avoid reentrancy */
|
||||
continue;
|
||||
@@ -1350,16 +1344,11 @@ _clutter_stage_maybe_relayout (ClutterActor *actor)
|
||||
|
||||
CLUTTER_SET_PRIVATE_FLAGS (queued_actor, CLUTTER_IN_RELAYOUT);
|
||||
|
||||
old_version = priv->pending_relayouts_version;
|
||||
clutter_actor_allocate_preferred_size (queued_actor);
|
||||
|
||||
CLUTTER_UNSET_PRIVATE_FLAGS (queued_actor, CLUTTER_IN_RELAYOUT);
|
||||
|
||||
count++;
|
||||
|
||||
/* Prevent using an iterator that's been invalidated */
|
||||
if (old_version != priv->pending_relayouts_version)
|
||||
g_hash_table_iter_init (&iter, priv->pending_relayouts);
|
||||
}
|
||||
|
||||
CLUTTER_NOTE (ACTOR, "<<< Completed recomputing layout of %d subtrees", count);
|
||||
@@ -1418,12 +1407,12 @@ _clutter_stage_check_updated_pointers (ClutterStage *stage)
|
||||
ClutterBackend *backend;
|
||||
ClutterSeat *seat;
|
||||
GSList *updating = NULL;
|
||||
GList *l, *devices;
|
||||
const GList *l, *devices;
|
||||
graphene_point_t point;
|
||||
|
||||
backend = clutter_get_default_backend ();
|
||||
seat = clutter_backend_get_default_seat (backend);
|
||||
devices = clutter_seat_list_devices (seat);
|
||||
devices = clutter_seat_peek_devices (seat);
|
||||
|
||||
for (l = devices; l; l = l->next)
|
||||
{
|
||||
@@ -1463,11 +1452,17 @@ _clutter_stage_check_updated_pointers (ClutterStage *stage)
|
||||
}
|
||||
}
|
||||
|
||||
g_list_free (devices);
|
||||
|
||||
return updating;
|
||||
}
|
||||
|
||||
static void
|
||||
update_actor_stage_views (ClutterStage *stage)
|
||||
{
|
||||
ClutterActor *actor = CLUTTER_ACTOR (stage);
|
||||
|
||||
clutter_actor_update_stage_views (actor);
|
||||
}
|
||||
|
||||
/**
|
||||
* _clutter_stage_do_update:
|
||||
* @stage: A #ClutterStage
|
||||
@@ -1515,6 +1510,10 @@ _clutter_stage_do_update (ClutterStage *stage)
|
||||
if (stage_was_relayout)
|
||||
pointers = _clutter_stage_check_updated_pointers (stage);
|
||||
|
||||
COGL_TRACE_BEGIN (ClutterStageUpdateActorStageViews, "Actor stage-views");
|
||||
update_actor_stage_views (stage);
|
||||
COGL_TRACE_END (ClutterStageUpdateActorStageViews);
|
||||
|
||||
COGL_TRACE_BEGIN (ClutterStagePaint, "Paint");
|
||||
|
||||
clutter_stage_maybe_finish_queue_redraws (stage);
|
||||
@@ -1910,7 +1909,9 @@ clutter_stage_dispose (GObject *object)
|
||||
(GDestroyNotify) free_queue_redraw_entry);
|
||||
priv->pending_queue_redraws = NULL;
|
||||
|
||||
g_clear_pointer (&priv->pending_relayouts, g_hash_table_destroy);
|
||||
g_slist_free_full (priv->pending_relayouts,
|
||||
(GDestroyNotify) g_object_unref);
|
||||
priv->pending_relayouts = NULL;
|
||||
|
||||
/* this will release the reference on the stage */
|
||||
stage_manager = clutter_stage_manager_get_default ();
|
||||
@@ -2147,7 +2148,7 @@ clutter_stage_class_init (ClutterStageClass *klass)
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 2,
|
||||
CLUTTER_TYPE_STAGE_VIEW,
|
||||
G_TYPE_POINTER);
|
||||
CAIRO_GOBJECT_TYPE_REGION);
|
||||
|
||||
/**
|
||||
* ClutterStage::presented: (skip)
|
||||
@@ -2224,10 +2225,6 @@ clutter_stage_init (ClutterStage *self)
|
||||
clutter_actor_set_background_color (CLUTTER_ACTOR (self),
|
||||
&default_stage_color);
|
||||
|
||||
priv->pending_relayouts = g_hash_table_new_full (NULL,
|
||||
NULL,
|
||||
g_object_unref,
|
||||
NULL);
|
||||
clutter_stage_queue_actor_relayout (self, CLUTTER_ACTOR (self));
|
||||
|
||||
clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE);
|
||||
@@ -3171,37 +3168,6 @@ _clutter_stage_maybe_setup_viewport (ClutterStage *stage,
|
||||
|
||||
#undef _DEG_TO_RAD
|
||||
|
||||
/**
|
||||
* clutter_stage_ensure_redraw:
|
||||
* @stage: a #ClutterStage
|
||||
*
|
||||
* Ensures that @stage is redrawn
|
||||
*
|
||||
* This function should not be called by applications: it is
|
||||
* used when embedding a #ClutterStage into a toolkit with
|
||||
* another windowing system, like GTK+.
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
void
|
||||
clutter_stage_ensure_redraw (ClutterStage *stage)
|
||||
{
|
||||
ClutterMasterClock *master_clock;
|
||||
ClutterStagePrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
||||
|
||||
priv = stage->priv;
|
||||
|
||||
if (!_clutter_stage_needs_update (stage))
|
||||
clutter_stage_schedule_update (stage);
|
||||
|
||||
priv->redraw_pending = TRUE;
|
||||
|
||||
master_clock = _clutter_master_clock_get_default ();
|
||||
_clutter_master_clock_start_running (master_clock);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_stage_is_redraw_queued: (skip)
|
||||
*/
|
||||
@@ -4107,20 +4073,29 @@ clutter_stage_get_capture_final_size (ClutterStage *stage,
|
||||
int *out_height,
|
||||
float *out_scale)
|
||||
{
|
||||
float max_scale;
|
||||
float max_scale = 1.0;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE);
|
||||
|
||||
if (rect)
|
||||
{
|
||||
graphene_rect_t capture_rect;
|
||||
g_autoptr (GList) views = NULL;
|
||||
GList *l;
|
||||
|
||||
_clutter_util_rect_from_rectangle (rect, &capture_rect);
|
||||
if (!_clutter_stage_get_max_view_scale_factor_for_rect (stage,
|
||||
&capture_rect,
|
||||
&max_scale))
|
||||
views = clutter_stage_get_views_for_rect (stage, &capture_rect);
|
||||
|
||||
if (!views)
|
||||
return FALSE;
|
||||
|
||||
for (l = views; l; l = l->next)
|
||||
{
|
||||
ClutterStageView *view = l->data;
|
||||
|
||||
max_scale = MAX (clutter_stage_view_get_scale (view), max_scale);
|
||||
}
|
||||
|
||||
if (out_width)
|
||||
*out_width = (gint) roundf (rect->width * max_scale);
|
||||
|
||||
@@ -4201,8 +4176,8 @@ clutter_stage_paint_to_buffer (ClutterStage *stage,
|
||||
CoglFramebuffer *framebuffer;
|
||||
CoglBitmap *bitmap;
|
||||
|
||||
texture_width = (int) ceilf (rect->width * scale);
|
||||
texture_height = (int) ceilf (rect->height * scale);
|
||||
texture_width = (int) roundf (rect->width * scale);
|
||||
texture_height = (int) roundf (rect->height * scale);
|
||||
texture = cogl_texture_2d_new_with_size (cogl_context,
|
||||
texture_width,
|
||||
texture_height);
|
||||
@@ -4401,18 +4376,17 @@ clutter_stage_peek_stage_views (ClutterStage *stage)
|
||||
}
|
||||
|
||||
void
|
||||
clutter_stage_update_resource_scales (ClutterStage *stage)
|
||||
clutter_stage_clear_stage_views (ClutterStage *stage)
|
||||
{
|
||||
_clutter_actor_queue_update_resource_scale_recursive (CLUTTER_ACTOR (stage));
|
||||
clutter_actor_clear_stage_views_recursive (CLUTTER_ACTOR (stage));
|
||||
}
|
||||
|
||||
gboolean
|
||||
_clutter_stage_get_max_view_scale_factor_for_rect (ClutterStage *stage,
|
||||
graphene_rect_t *rect,
|
||||
float *view_scale)
|
||||
GList *
|
||||
clutter_stage_get_views_for_rect (ClutterStage *stage,
|
||||
const graphene_rect_t *rect)
|
||||
{
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
float scale = 0.0f;
|
||||
GList *views_for_rect = NULL;
|
||||
GList *l;
|
||||
|
||||
for (l = _clutter_stage_window_get_views (priv->impl); l; l = l->next)
|
||||
@@ -4425,12 +4399,8 @@ _clutter_stage_get_max_view_scale_factor_for_rect (ClutterStage *stage,
|
||||
_clutter_util_rect_from_rectangle (&view_layout, &view_rect);
|
||||
|
||||
if (graphene_rect_intersection (&view_rect, rect, NULL))
|
||||
scale = MAX (clutter_stage_view_get_scale (view), scale);
|
||||
views_for_rect = g_list_prepend (views_for_rect, view);
|
||||
}
|
||||
|
||||
if (scale == 0.0)
|
||||
return FALSE;
|
||||
|
||||
*view_scale = scale;
|
||||
return TRUE;
|
||||
return views_for_rect;
|
||||
}
|
||||
|
@@ -195,8 +195,6 @@ guchar * clutter_stage_read_pixels (ClutterStage
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_stage_ensure_viewport (ClutterStage *stage);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_stage_ensure_redraw (ClutterStage *stage);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_stage_is_redraw_queued (ClutterStage *stage);
|
||||
|
@@ -172,7 +172,6 @@ enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_LOOP,
|
||||
PROP_DELAY,
|
||||
PROP_DURATION,
|
||||
PROP_DIRECTION,
|
||||
@@ -290,23 +289,6 @@ clutter_timeline_add_marker_internal (ClutterTimeline *timeline,
|
||||
g_hash_table_insert (priv->markers_by_name, marker->name, marker);
|
||||
}
|
||||
|
||||
static inline void
|
||||
clutter_timeline_set_loop_internal (ClutterTimeline *timeline,
|
||||
gboolean loop)
|
||||
{
|
||||
gint old_repeat_count;
|
||||
|
||||
old_repeat_count = timeline->priv->repeat_count;
|
||||
|
||||
if (loop)
|
||||
clutter_timeline_set_repeat_count (timeline, -1);
|
||||
else
|
||||
clutter_timeline_set_repeat_count (timeline, 0);
|
||||
|
||||
if (old_repeat_count != timeline->priv->repeat_count)
|
||||
g_object_notify_by_pspec (G_OBJECT (timeline), obj_props[PROP_LOOP]);
|
||||
}
|
||||
|
||||
/* Scriptable */
|
||||
typedef struct _ParseClosure {
|
||||
ClutterTimeline *timeline;
|
||||
@@ -448,10 +430,6 @@ clutter_timeline_set_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_LOOP:
|
||||
clutter_timeline_set_loop_internal (timeline, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
case PROP_DELAY:
|
||||
clutter_timeline_set_delay (timeline, g_value_get_uint (value));
|
||||
break;
|
||||
@@ -493,10 +471,6 @@ clutter_timeline_get_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_LOOP:
|
||||
g_value_set_boolean (value, priv->repeat_count != 0);
|
||||
break;
|
||||
|
||||
case PROP_DELAY:
|
||||
g_value_set_uint (value, priv->delay);
|
||||
break;
|
||||
@@ -572,25 +546,6 @@ clutter_timeline_class_init (ClutterTimelineClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
/**
|
||||
* ClutterTimeline:loop:
|
||||
*
|
||||
* Whether the timeline should automatically rewind and restart.
|
||||
*
|
||||
* As a side effect, setting this property to %TRUE will set the
|
||||
* #ClutterTimeline:repeat-count property to -1, while setting this
|
||||
* property to %FALSE will set the #ClutterTimeline:repeat-count
|
||||
* property to 0.
|
||||
*
|
||||
* Deprecated: 1.10: Use the #ClutterTimeline:repeat-count property instead.
|
||||
*/
|
||||
obj_props[PROP_LOOP] =
|
||||
g_param_spec_boolean ("loop",
|
||||
P_("Loop"),
|
||||
P_("Should the timeline automatically restart"),
|
||||
FALSE,
|
||||
CLUTTER_PARAM_READWRITE | G_PARAM_DEPRECATED);
|
||||
|
||||
/**
|
||||
* ClutterTimeline:delay:
|
||||
*
|
||||
@@ -1251,45 +1206,6 @@ clutter_timeline_stop (ClutterTimeline *timeline)
|
||||
g_signal_emit (timeline, timeline_signals[STOPPED], 0, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_timeline_set_loop:
|
||||
* @timeline: a #ClutterTimeline
|
||||
* @loop: %TRUE for enable looping
|
||||
*
|
||||
* Sets whether @timeline should loop.
|
||||
*
|
||||
* This function is equivalent to calling clutter_timeline_set_repeat_count()
|
||||
* with -1 if @loop is %TRUE, and with 0 if @loop is %FALSE.
|
||||
*
|
||||
* Deprecated: 1.10: Use clutter_timeline_set_repeat_count() instead.
|
||||
*/
|
||||
void
|
||||
clutter_timeline_set_loop (ClutterTimeline *timeline,
|
||||
gboolean loop)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_TIMELINE (timeline));
|
||||
|
||||
clutter_timeline_set_loop_internal (timeline, loop);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_timeline_get_loop:
|
||||
* @timeline: a #ClutterTimeline
|
||||
*
|
||||
* Gets whether @timeline is looping
|
||||
*
|
||||
* Return value: %TRUE if the timeline is looping
|
||||
*
|
||||
* Deprecated: 1.10: Use clutter_timeline_get_repeat_count() instead.
|
||||
*/
|
||||
gboolean
|
||||
clutter_timeline_get_loop (ClutterTimeline *timeline)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), FALSE);
|
||||
|
||||
return timeline->priv->repeat_count != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_timeline_rewind:
|
||||
* @timeline: A #ClutterTimeline
|
||||
@@ -1405,49 +1321,11 @@ clutter_timeline_is_playing (ClutterTimeline *timeline)
|
||||
return timeline->priv->is_playing;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_timeline_clone:
|
||||
* @timeline: #ClutterTimeline to duplicate.
|
||||
*
|
||||
* Create a new #ClutterTimeline instance which has property values
|
||||
* matching that of supplied timeline. The cloned timeline will not
|
||||
* be started and will not be positioned to the current position of
|
||||
* the original @timeline: you will have to start it with
|
||||
* clutter_timeline_start().
|
||||
*
|
||||
* The only cloned properties are:
|
||||
*
|
||||
* - #ClutterTimeline:duration
|
||||
* - #ClutterTimeline:loop
|
||||
* - #ClutterTimeline:delay
|
||||
* - #ClutterTimeline:direction
|
||||
*
|
||||
* Return value: (transfer full): a new #ClutterTimeline, cloned
|
||||
* from @timeline
|
||||
*
|
||||
* Since: 0.4
|
||||
*
|
||||
* Deprecated: 1.10: Use clutter_timeline_new() or g_object_new()
|
||||
* instead
|
||||
*/
|
||||
ClutterTimeline *
|
||||
clutter_timeline_clone (ClutterTimeline *timeline)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), NULL);
|
||||
|
||||
return g_object_new (CLUTTER_TYPE_TIMELINE,
|
||||
"duration", timeline->priv->duration,
|
||||
"loop", timeline->priv->repeat_count != 0,
|
||||
"delay", timeline->priv->delay,
|
||||
"direction", timeline->priv->direction,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_timeline_new:
|
||||
* @msecs: Duration of the timeline in milliseconds
|
||||
* @duration_ms: Duration of the timeline in milliseconds
|
||||
*
|
||||
* Creates a new #ClutterTimeline with a duration of @msecs.
|
||||
* Creates a new #ClutterTimeline with a duration of @duration_ms milli seconds.
|
||||
*
|
||||
* Return value: the newly created #ClutterTimeline instance. Use
|
||||
* g_object_unref() when done using it
|
||||
@@ -1455,10 +1333,10 @@ clutter_timeline_clone (ClutterTimeline *timeline)
|
||||
* Since: 0.6
|
||||
*/
|
||||
ClutterTimeline *
|
||||
clutter_timeline_new (guint msecs)
|
||||
clutter_timeline_new (guint duration_ms)
|
||||
{
|
||||
return g_object_new (CLUTTER_TYPE_TIMELINE,
|
||||
"duration", msecs,
|
||||
"duration", duration_ms,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
@@ -119,7 +119,7 @@ CLUTTER_EXPORT
|
||||
GType clutter_timeline_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterTimeline * clutter_timeline_new (guint msecs);
|
||||
ClutterTimeline * clutter_timeline_new (guint duration_ms);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
guint clutter_timeline_get_duration (ClutterTimeline *timeline);
|
||||
|
@@ -174,6 +174,20 @@ struct _ClutterActorBox
|
||||
*/
|
||||
#define CLUTTER_ACTOR_BOX_INIT_ZERO CLUTTER_ACTOR_BOX_INIT (0.f, 0.f, 0.f, 0.f)
|
||||
|
||||
/**
|
||||
* CLUTTER_ACTOR_BOX_UNINITIALIZED:
|
||||
*
|
||||
* A simple macro for creating a #ClutterActorBox with a size of -1 when
|
||||
* declaring it, e.g.:
|
||||
*
|
||||
* |[
|
||||
* ClutterActorBox box = CLUTTER_ACTOR_BOX_UNINITIALIZED;
|
||||
* ]|
|
||||
*/
|
||||
|
||||
|
||||
#define CLUTTER_ACTOR_BOX_UNINITIALIZED { .x1 = INFINITY, .y1 = INFINITY, .x2 = -INFINITY, .y2 = -INFINITY }
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType clutter_actor_box_get_type (void) G_GNUC_CONST;
|
||||
CLUTTER_EXPORT
|
||||
@@ -252,6 +266,9 @@ CLUTTER_EXPORT
|
||||
void clutter_actor_box_scale (ClutterActorBox *box,
|
||||
gfloat scale);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_box_is_initialized (ClutterActorBox *box);
|
||||
|
||||
/**
|
||||
* ClutterKnot:
|
||||
* @x: X coordinate of the knot
|
||||
|
@@ -551,7 +551,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
CoglFramebuffer *onscreen = clutter_stage_view_get_onscreen (view);
|
||||
cairo_rectangle_int_t view_rect;
|
||||
gboolean is_full_redraw;
|
||||
gboolean use_clipped_redraw;
|
||||
gboolean use_clipped_redraw = TRUE;
|
||||
gboolean can_blit_sub_buffer;
|
||||
gboolean has_buffer_age;
|
||||
gboolean swap_with_damage;
|
||||
@@ -561,7 +561,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
cairo_region_t *swap_region;
|
||||
float fb_scale;
|
||||
int fb_width, fb_height;
|
||||
int buffer_age;
|
||||
int buffer_age = 0;
|
||||
gboolean res;
|
||||
|
||||
clutter_stage_view_get_layout (view, &view_rect);
|
||||
|
@@ -26,16 +26,6 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
CLUTTER_DEPRECATED_FOR(clutter_timeline_new)
|
||||
ClutterTimeline * clutter_timeline_clone (ClutterTimeline *timeline);
|
||||
|
||||
CLUTTER_DEPRECATED_FOR(clutter_timeline_set_repeat_count)
|
||||
void clutter_timeline_set_loop (ClutterTimeline *timeline,
|
||||
gboolean loop);
|
||||
|
||||
CLUTTER_DEPRECATED_FOR(clutter_timeline_get_repeat_count)
|
||||
gboolean clutter_timeline_get_loop (ClutterTimeline *timeline);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_TIMELINE_PRIVATE_H__ */
|
||||
|
@@ -48,7 +48,6 @@
|
||||
#include "cogl1-context.h"
|
||||
#include "cogl-sub-texture.h"
|
||||
#include "cogl-gtype-private.h"
|
||||
#include "driver/gl/cogl-pipeline-opengl-private.h"
|
||||
#include "driver/gl/cogl-texture-gl-private.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@@ -51,11 +51,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* This isn't defined in the GLES headers */
|
||||
#ifndef GL_UNSIGNED_INT
|
||||
#define GL_UNSIGNED_INT 0x1405
|
||||
#endif
|
||||
|
||||
static void _cogl_attribute_free (CoglAttribute *attribute);
|
||||
|
||||
COGL_OBJECT_DEFINE (Attribute, attribute);
|
||||
|
@@ -34,7 +34,6 @@
|
||||
|
||||
#include "cogl-boxed-value.h"
|
||||
#include "cogl-context-private.h"
|
||||
#include "driver/gl/cogl-util-gl-private.h"
|
||||
|
||||
gboolean
|
||||
_cogl_boxed_value_equal (const CoglBoxedValue *bva,
|
||||
@@ -286,90 +285,5 @@ _cogl_boxed_value_set_uniform (CoglContext *ctx,
|
||||
GLint location,
|
||||
const CoglBoxedValue *value)
|
||||
{
|
||||
switch (value->type)
|
||||
{
|
||||
case COGL_BOXED_NONE:
|
||||
break;
|
||||
|
||||
case COGL_BOXED_INT:
|
||||
{
|
||||
const int *ptr;
|
||||
|
||||
if (value->count == 1)
|
||||
ptr = value->v.int_value;
|
||||
else
|
||||
ptr = value->v.int_array;
|
||||
|
||||
switch (value->size)
|
||||
{
|
||||
case 1:
|
||||
GE( ctx, glUniform1iv (location, value->count, ptr) );
|
||||
break;
|
||||
case 2:
|
||||
GE( ctx, glUniform2iv (location, value->count, ptr) );
|
||||
break;
|
||||
case 3:
|
||||
GE( ctx, glUniform3iv (location, value->count, ptr) );
|
||||
break;
|
||||
case 4:
|
||||
GE( ctx, glUniform4iv (location, value->count, ptr) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case COGL_BOXED_FLOAT:
|
||||
{
|
||||
const float *ptr;
|
||||
|
||||
if (value->count == 1)
|
||||
ptr = value->v.float_value;
|
||||
else
|
||||
ptr = value->v.float_array;
|
||||
|
||||
switch (value->size)
|
||||
{
|
||||
case 1:
|
||||
GE( ctx, glUniform1fv (location, value->count, ptr) );
|
||||
break;
|
||||
case 2:
|
||||
GE( ctx, glUniform2fv (location, value->count, ptr) );
|
||||
break;
|
||||
case 3:
|
||||
GE( ctx, glUniform3fv (location, value->count, ptr) );
|
||||
break;
|
||||
case 4:
|
||||
GE( ctx, glUniform4fv (location, value->count, ptr) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case COGL_BOXED_MATRIX:
|
||||
{
|
||||
const float *ptr;
|
||||
|
||||
if (value->count == 1)
|
||||
ptr = value->v.matrix;
|
||||
else
|
||||
ptr = value->v.float_array;
|
||||
|
||||
switch (value->size)
|
||||
{
|
||||
case 2:
|
||||
GE( ctx, glUniformMatrix2fv (location, value->count,
|
||||
FALSE, ptr) );
|
||||
break;
|
||||
case 3:
|
||||
GE( ctx, glUniformMatrix3fv (location, value->count,
|
||||
FALSE, ptr) );
|
||||
break;
|
||||
case 4:
|
||||
GE( ctx, glUniformMatrix4fv (location, value->count,
|
||||
FALSE, ptr) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
ctx->driver_vtable->set_uniform (ctx, location, value);
|
||||
}
|
||||
|
@@ -46,7 +46,6 @@
|
||||
#include "cogl-pipeline-cache.h"
|
||||
#include "cogl-texture-2d.h"
|
||||
#include "cogl-sampler-cache-private.h"
|
||||
#include "cogl-gpu-info-private.h"
|
||||
#include "cogl-gl-header.h"
|
||||
#include "cogl-framebuffer-private.h"
|
||||
#include "cogl-onscreen-private.h"
|
||||
@@ -70,14 +69,12 @@ struct _CoglContext
|
||||
|
||||
CoglDriver driver;
|
||||
|
||||
/* Information about the GPU and driver which we can use to
|
||||
determine certain workarounds */
|
||||
CoglGpuInfo gpu;
|
||||
|
||||
/* vtables for the driver functions */
|
||||
const CoglDriverVtable *driver_vtable;
|
||||
const CoglTextureDriver *texture_driver;
|
||||
|
||||
void *driver_context;
|
||||
|
||||
int glsl_major;
|
||||
int glsl_minor;
|
||||
|
||||
@@ -124,9 +121,6 @@ struct _CoglContext
|
||||
|
||||
CoglMatrixEntry identity_entry;
|
||||
|
||||
GArray *texture_units;
|
||||
int active_texture_unit;
|
||||
|
||||
/* Only used for comparing other pipelines when reading pixels. */
|
||||
CoglPipeline *opaque_color_pipeline;
|
||||
|
||||
@@ -315,18 +309,4 @@ void
|
||||
_cogl_context_set_current_modelview_entry (CoglContext *context,
|
||||
CoglMatrixEntry *entry);
|
||||
|
||||
/*
|
||||
* _cogl_context_get_gl_extensions:
|
||||
* @context: A CoglContext
|
||||
*
|
||||
* Return value: a NULL-terminated array of strings representing the
|
||||
* supported extensions by the current driver. This array is owned
|
||||
* by the caller and should be freed with g_strfreev().
|
||||
*/
|
||||
char **
|
||||
_cogl_context_get_gl_extensions (CoglContext *context);
|
||||
|
||||
const char *
|
||||
_cogl_context_get_gl_version (CoglContext *context);
|
||||
|
||||
#endif /* __COGL_CONTEXT_PRIVATE_H */
|
||||
|
@@ -45,40 +45,12 @@
|
||||
#include "cogl-onscreen-private.h"
|
||||
#include "cogl-attribute-private.h"
|
||||
#include "cogl1-context.h"
|
||||
#include "cogl-gpu-info-private.h"
|
||||
#include "cogl-gtype-private.h"
|
||||
#include "winsys/cogl-winsys-private.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* These aren't defined in the GLES headers */
|
||||
#ifndef GL_POINT_SPRITE
|
||||
#define GL_POINT_SPRITE 0x8861
|
||||
#endif
|
||||
|
||||
#ifndef GL_NUM_EXTENSIONS
|
||||
#define GL_NUM_EXTENSIONS 0x821D
|
||||
#endif
|
||||
|
||||
/* This is a relatively new extension */
|
||||
#ifndef GL_PURGED_CONTEXT_RESET_NV
|
||||
#define GL_PURGED_CONTEXT_RESET_NV 0x92BB
|
||||
#endif
|
||||
|
||||
/* These aren't defined in the GLES2 headers */
|
||||
#ifndef GL_GUILTY_CONTEXT_RESET_ARB
|
||||
#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253
|
||||
#endif
|
||||
|
||||
#ifndef GL_INNOCENT_CONTEXT_RESET_ARB
|
||||
#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254
|
||||
#endif
|
||||
|
||||
#ifndef GL_UNKNOWN_CONTEXT_RESET_ARB
|
||||
#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255
|
||||
#endif
|
||||
|
||||
static void _cogl_context_free (CoglContext *context);
|
||||
|
||||
COGL_OBJECT_DEFINE (Context, context);
|
||||
@@ -470,94 +442,6 @@ _cogl_context_set_current_modelview_entry (CoglContext *context,
|
||||
context->current_modelview_entry = entry;
|
||||
}
|
||||
|
||||
char **
|
||||
_cogl_context_get_gl_extensions (CoglContext *context)
|
||||
{
|
||||
const char *env_disabled_extensions;
|
||||
char **ret;
|
||||
|
||||
/* In GL 3, querying GL_EXTENSIONS is deprecated so we have to build
|
||||
* the array using glGetStringi instead */
|
||||
#ifdef HAVE_COGL_GL
|
||||
if (context->driver == COGL_DRIVER_GL3)
|
||||
{
|
||||
int num_extensions, i;
|
||||
|
||||
context->glGetIntegerv (GL_NUM_EXTENSIONS, &num_extensions);
|
||||
|
||||
ret = g_malloc (sizeof (char *) * (num_extensions + 1));
|
||||
|
||||
for (i = 0; i < num_extensions; i++)
|
||||
{
|
||||
const char *ext =
|
||||
(const char *) context->glGetStringi (GL_EXTENSIONS, i);
|
||||
ret[i] = g_strdup (ext);
|
||||
}
|
||||
|
||||
ret[num_extensions] = NULL;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
const char *all_extensions =
|
||||
(const char *) context->glGetString (GL_EXTENSIONS);
|
||||
|
||||
ret = g_strsplit (all_extensions, " ", 0 /* max tokens */);
|
||||
}
|
||||
|
||||
if ((env_disabled_extensions = g_getenv ("COGL_DISABLE_GL_EXTENSIONS")))
|
||||
{
|
||||
char **split_env_disabled_extensions;
|
||||
char **src, **dst;
|
||||
|
||||
if (env_disabled_extensions)
|
||||
split_env_disabled_extensions =
|
||||
g_strsplit (env_disabled_extensions,
|
||||
",",
|
||||
0 /* no max tokens */);
|
||||
else
|
||||
split_env_disabled_extensions = NULL;
|
||||
|
||||
for (dst = ret, src = ret;
|
||||
*src;
|
||||
src++)
|
||||
{
|
||||
char **d;
|
||||
|
||||
if (split_env_disabled_extensions)
|
||||
for (d = split_env_disabled_extensions; *d; d++)
|
||||
if (!strcmp (*src, *d))
|
||||
goto disabled;
|
||||
|
||||
*(dst++) = *src;
|
||||
continue;
|
||||
|
||||
disabled:
|
||||
g_free (*src);
|
||||
continue;
|
||||
}
|
||||
|
||||
*dst = NULL;
|
||||
|
||||
if (split_env_disabled_extensions)
|
||||
g_strfreev (split_env_disabled_extensions);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char *
|
||||
_cogl_context_get_gl_version (CoglContext *context)
|
||||
{
|
||||
const char *version_override;
|
||||
|
||||
if ((version_override = g_getenv ("COGL_OVERRIDE_GL_VERSION")))
|
||||
return version_override;
|
||||
else
|
||||
return (const char *) context->glGetString (GL_VERSION);
|
||||
|
||||
}
|
||||
|
||||
int64_t
|
||||
cogl_get_clock_time (CoglContext *context)
|
||||
{
|
||||
@@ -572,24 +456,11 @@ cogl_get_clock_time (CoglContext *context)
|
||||
CoglGraphicsResetStatus
|
||||
cogl_get_graphics_reset_status (CoglContext *context)
|
||||
{
|
||||
if (!context->glGetGraphicsResetStatus)
|
||||
return COGL_GRAPHICS_RESET_STATUS_NO_ERROR;
|
||||
|
||||
switch (context->glGetGraphicsResetStatus ())
|
||||
{
|
||||
case GL_GUILTY_CONTEXT_RESET_ARB:
|
||||
return COGL_GRAPHICS_RESET_STATUS_GUILTY_CONTEXT_RESET;
|
||||
|
||||
case GL_INNOCENT_CONTEXT_RESET_ARB:
|
||||
return COGL_GRAPHICS_RESET_STATUS_INNOCENT_CONTEXT_RESET;
|
||||
|
||||
case GL_UNKNOWN_CONTEXT_RESET_ARB:
|
||||
return COGL_GRAPHICS_RESET_STATUS_UNKNOWN_CONTEXT_RESET;
|
||||
|
||||
case GL_PURGED_CONTEXT_RESET_NV:
|
||||
return COGL_GRAPHICS_RESET_STATUS_PURGED_CONTEXT_RESET;
|
||||
|
||||
default:
|
||||
return COGL_GRAPHICS_RESET_STATUS_NO_ERROR;
|
||||
}
|
||||
return context->driver_vtable->get_graphics_reset_status (context);
|
||||
}
|
||||
|
||||
gboolean
|
||||
cogl_context_is_hardware_accelerated (CoglContext *context)
|
||||
{
|
||||
return context->driver_vtable->is_hardware_accelerated (context);
|
||||
}
|
||||
|
@@ -357,6 +357,16 @@ typedef enum _CoglGraphicsResetStatus
|
||||
COGL_EXPORT CoglGraphicsResetStatus
|
||||
cogl_get_graphics_reset_status (CoglContext *context);
|
||||
|
||||
/**
|
||||
* cogl_context_is_hardware_accelerated:
|
||||
* @context: a #CoglContext pointer
|
||||
*
|
||||
* Returns: %TRUE if the @context is hardware accelerated, or %FALSE if
|
||||
* not.
|
||||
*/
|
||||
COGL_EXPORT gboolean
|
||||
cogl_context_is_hardware_accelerated (CoglContext *context);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __COGL_CONTEXT_H__ */
|
||||
|
@@ -35,6 +35,7 @@
|
||||
#include "cogl-offscreen.h"
|
||||
#include "cogl-framebuffer-private.h"
|
||||
#include "cogl-attribute-private.h"
|
||||
#include "cogl-sampler-cache-private.h"
|
||||
|
||||
typedef struct _CoglDriverVtable CoglDriverVtable;
|
||||
|
||||
@@ -46,6 +47,12 @@ struct _CoglDriverVtable
|
||||
void
|
||||
(* context_deinit) (CoglContext *context);
|
||||
|
||||
gboolean
|
||||
(* is_hardware_accelerated) (CoglContext *context);
|
||||
|
||||
CoglGraphicsResetStatus
|
||||
(* get_graphics_reset_status) (CoglContext *context);
|
||||
|
||||
/* TODO: factor this out since this is OpenGL specific and
|
||||
* so can be ignored by non-OpenGL drivers. */
|
||||
gboolean
|
||||
@@ -262,6 +269,19 @@ struct _CoglDriverVtable
|
||||
const void *data,
|
||||
unsigned int size,
|
||||
GError **error);
|
||||
|
||||
void
|
||||
(*sampler_init) (CoglContext *context,
|
||||
CoglSamplerCacheEntry *entry);
|
||||
|
||||
void
|
||||
(*sampler_free) (CoglContext *context,
|
||||
CoglSamplerCacheEntry *entry);
|
||||
|
||||
void
|
||||
(* set_uniform) (CoglContext *ctx,
|
||||
GLint location,
|
||||
const CoglBoxedValue *value);
|
||||
};
|
||||
|
||||
#define COGL_DRIVER_ERROR (_cogl_driver_error_quark ())
|
||||
|
@@ -43,8 +43,6 @@ struct _CoglFrameInfo
|
||||
float refresh_rate;
|
||||
|
||||
int64_t global_frame_counter;
|
||||
|
||||
CoglOutput *output;
|
||||
};
|
||||
|
||||
CoglFrameInfo *_cogl_frame_info_new (void);
|
||||
|
@@ -72,12 +72,6 @@ cogl_frame_info_get_refresh_rate (CoglFrameInfo *info)
|
||||
return info->refresh_rate;
|
||||
}
|
||||
|
||||
CoglOutput *
|
||||
cogl_frame_info_get_output (CoglFrameInfo *info)
|
||||
{
|
||||
return info->output;
|
||||
}
|
||||
|
||||
int64_t
|
||||
cogl_frame_info_get_global_frame_counter (CoglFrameInfo *info)
|
||||
{
|
||||
|
@@ -126,20 +126,6 @@ int64_t cogl_frame_info_get_presentation_time (CoglFrameInfo *info);
|
||||
COGL_EXPORT
|
||||
float cogl_frame_info_get_refresh_rate (CoglFrameInfo *info);
|
||||
|
||||
/**
|
||||
* cogl_frame_info_get_output:
|
||||
* @info: a #CoglFrameInfo object
|
||||
*
|
||||
* Gets the #CoglOutput that the swapped frame was presented to.
|
||||
*
|
||||
* Return value: (transfer none): The #CoglOutput that the frame was
|
||||
* presented to, or %NULL if this could not be determined.
|
||||
* Since: 1.14
|
||||
* Stability: unstable
|
||||
*/
|
||||
COGL_EXPORT CoglOutput *
|
||||
cogl_frame_info_get_output (CoglFrameInfo *info);
|
||||
|
||||
/**
|
||||
* cogl_frame_info_get_global_frame_counter: (skip)
|
||||
*/
|
||||
|
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Cogl
|
||||
*
|
||||
* A Low Level GPU Graphics and Utilities API
|
||||
*
|
||||
* Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
#ifndef _COGL_GLSL_SHADER_PRIVATE_H_
|
||||
#define _COGL_GLSL_SHADER_PRIVATE_H_
|
||||
|
||||
void
|
||||
_cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
|
||||
GLuint shader_gl_handle,
|
||||
GLenum shader_gl_type,
|
||||
CoglPipeline *pipeline,
|
||||
GLsizei count_in,
|
||||
const char **strings_in,
|
||||
const GLint *lengths_in);
|
||||
|
||||
#endif /* _COGL_GLSL_SHADER_PRIVATE_H_ */
|
@@ -1,189 +0,0 @@
|
||||
/*
|
||||
* Cogl
|
||||
*
|
||||
* A Low Level GPU Graphics and Utilities API
|
||||
*
|
||||
* Copyright (C) 2012 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.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors:
|
||||
* Robert Bragg <robert@linux.intel.com>
|
||||
* Neil Roberts <neil@linux.intel.com>
|
||||
*/
|
||||
|
||||
#include "cogl-config.h"
|
||||
|
||||
#include "cogl-context-private.h"
|
||||
#include "cogl-glsl-shader-private.h"
|
||||
#include "cogl-glsl-shader-boilerplate.h"
|
||||
#include "driver/gl/cogl-util-gl-private.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
static gboolean
|
||||
add_layer_vertex_boilerplate_cb (CoglPipelineLayer *layer,
|
||||
void *user_data)
|
||||
{
|
||||
GString *layer_declarations = user_data;
|
||||
int unit_index = _cogl_pipeline_layer_get_unit_index (layer);
|
||||
g_string_append_printf (layer_declarations,
|
||||
"attribute vec4 cogl_tex_coord%d_in;\n"
|
||||
"#define cogl_texture_matrix%i cogl_texture_matrix[%i]\n"
|
||||
"#define cogl_tex_coord%i_out _cogl_tex_coord[%i]\n",
|
||||
layer->index,
|
||||
layer->index,
|
||||
unit_index,
|
||||
layer->index,
|
||||
unit_index);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
add_layer_fragment_boilerplate_cb (CoglPipelineLayer *layer,
|
||||
void *user_data)
|
||||
{
|
||||
GString *layer_declarations = user_data;
|
||||
g_string_append_printf (layer_declarations,
|
||||
"#define cogl_tex_coord%i_in _cogl_tex_coord[%i]\n",
|
||||
layer->index,
|
||||
_cogl_pipeline_layer_get_unit_index (layer));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
|
||||
GLuint shader_gl_handle,
|
||||
GLenum shader_gl_type,
|
||||
CoglPipeline *pipeline,
|
||||
GLsizei count_in,
|
||||
const char **strings_in,
|
||||
const GLint *lengths_in)
|
||||
{
|
||||
const char *vertex_boilerplate;
|
||||
const char *fragment_boilerplate;
|
||||
|
||||
const char **strings = g_alloca (sizeof (char *) * (count_in + 4));
|
||||
GLint *lengths = g_alloca (sizeof (GLint) * (count_in + 4));
|
||||
char *version_string;
|
||||
int count = 0;
|
||||
|
||||
int n_layers;
|
||||
|
||||
vertex_boilerplate = _COGL_VERTEX_SHADER_BOILERPLATE;
|
||||
fragment_boilerplate = _COGL_FRAGMENT_SHADER_BOILERPLATE;
|
||||
|
||||
version_string = g_strdup_printf ("#version %i\n\n",
|
||||
ctx->glsl_version_to_use);
|
||||
strings[count] = version_string;
|
||||
lengths[count++] = -1;
|
||||
|
||||
if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL))
|
||||
{
|
||||
static const char image_external_extension[] =
|
||||
"#extension GL_OES_EGL_image_external : require\n";
|
||||
strings[count] = image_external_extension;
|
||||
lengths[count++] = sizeof (image_external_extension) - 1;
|
||||
}
|
||||
|
||||
if (shader_gl_type == GL_VERTEX_SHADER)
|
||||
{
|
||||
strings[count] = vertex_boilerplate;
|
||||
lengths[count++] = strlen (vertex_boilerplate);
|
||||
}
|
||||
else if (shader_gl_type == GL_FRAGMENT_SHADER)
|
||||
{
|
||||
strings[count] = fragment_boilerplate;
|
||||
lengths[count++] = strlen (fragment_boilerplate);
|
||||
}
|
||||
|
||||
n_layers = cogl_pipeline_get_n_layers (pipeline);
|
||||
if (n_layers)
|
||||
{
|
||||
GString *layer_declarations = ctx->codegen_boilerplate_buffer;
|
||||
g_string_set_size (layer_declarations, 0);
|
||||
|
||||
g_string_append_printf (layer_declarations,
|
||||
"varying vec4 _cogl_tex_coord[%d];\n",
|
||||
n_layers);
|
||||
|
||||
if (shader_gl_type == GL_VERTEX_SHADER)
|
||||
{
|
||||
g_string_append_printf (layer_declarations,
|
||||
"uniform mat4 cogl_texture_matrix[%d];\n",
|
||||
n_layers);
|
||||
|
||||
_cogl_pipeline_foreach_layer_internal (pipeline,
|
||||
add_layer_vertex_boilerplate_cb,
|
||||
layer_declarations);
|
||||
}
|
||||
else if (shader_gl_type == GL_FRAGMENT_SHADER)
|
||||
{
|
||||
_cogl_pipeline_foreach_layer_internal (pipeline,
|
||||
add_layer_fragment_boilerplate_cb,
|
||||
layer_declarations);
|
||||
}
|
||||
|
||||
strings[count] = layer_declarations->str;
|
||||
lengths[count++] = -1; /* null terminated */
|
||||
}
|
||||
|
||||
memcpy (strings + count, strings_in, sizeof (char *) * count_in);
|
||||
if (lengths_in)
|
||||
memcpy (lengths + count, lengths_in, sizeof (GLint) * count_in);
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count_in; i++)
|
||||
lengths[count + i] = -1; /* null terminated */
|
||||
}
|
||||
count += count_in;
|
||||
|
||||
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SHOW_SOURCE)))
|
||||
{
|
||||
GString *buf = g_string_new (NULL);
|
||||
int i;
|
||||
|
||||
g_string_append_printf (buf,
|
||||
"%s shader:\n",
|
||||
shader_gl_type == GL_VERTEX_SHADER ?
|
||||
"vertex" : "fragment");
|
||||
for (i = 0; i < count; i++)
|
||||
if (lengths[i] != -1)
|
||||
g_string_append_len (buf, strings[i], lengths[i]);
|
||||
else
|
||||
g_string_append (buf, strings[i]);
|
||||
|
||||
g_message ("%s", buf->str);
|
||||
|
||||
g_string_free (buf, TRUE);
|
||||
}
|
||||
|
||||
GE( ctx, glShaderSource (shader_gl_handle, count,
|
||||
(const char **) strings, lengths) );
|
||||
|
||||
g_free (version_string);
|
||||
}
|
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Cogl
|
||||
*
|
||||
* A Low Level GPU Graphics and Utilities API
|
||||
*
|
||||
* Copyright (C) 2012 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.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __COGL_GPU_INFO_PRIVATE_H
|
||||
#define __COGL_GPU_INFO_PRIVATE_H
|
||||
|
||||
#include "cogl-context.h"
|
||||
|
||||
typedef enum _CoglGpuInfoArchitectureFlag
|
||||
{
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_IMMEDIATE_MODE,
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_TILED,
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_SOFTWARE,
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_IMMEDIATE_MODE,
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_DEFERRED,
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_SOFTWARE
|
||||
} CoglGpuInfoArchitectureFlag;
|
||||
|
||||
typedef enum _CoglGpuInfoArchitecture
|
||||
{
|
||||
COGL_GPU_INFO_ARCHITECTURE_UNKNOWN,
|
||||
COGL_GPU_INFO_ARCHITECTURE_SANDYBRIDGE,
|
||||
COGL_GPU_INFO_ARCHITECTURE_SGX,
|
||||
COGL_GPU_INFO_ARCHITECTURE_MALI,
|
||||
COGL_GPU_INFO_ARCHITECTURE_LLVMPIPE,
|
||||
COGL_GPU_INFO_ARCHITECTURE_SOFTPIPE,
|
||||
COGL_GPU_INFO_ARCHITECTURE_SWRAST
|
||||
} CoglGpuInfoArchitecture;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
COGL_GPU_INFO_VENDOR_UNKNOWN,
|
||||
COGL_GPU_INFO_VENDOR_INTEL,
|
||||
COGL_GPU_INFO_VENDOR_IMAGINATION_TECHNOLOGIES,
|
||||
COGL_GPU_INFO_VENDOR_ARM,
|
||||
COGL_GPU_INFO_VENDOR_QUALCOMM,
|
||||
COGL_GPU_INFO_VENDOR_NVIDIA,
|
||||
COGL_GPU_INFO_VENDOR_ATI,
|
||||
COGL_GPU_INFO_VENDOR_MESA
|
||||
} CoglGpuInfoVendor;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
COGL_GPU_INFO_DRIVER_PACKAGE_UNKNOWN,
|
||||
COGL_GPU_INFO_DRIVER_PACKAGE_MESA
|
||||
} CoglGpuInfoDriverPackage;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
COGL_GPU_INFO_DRIVER_STUB
|
||||
} CoglGpuInfoDriverBug;
|
||||
|
||||
typedef struct _CoglGpuInfoVersion CoglGpuInfoVersion;
|
||||
|
||||
typedef struct _CoglGpuInfo CoglGpuInfo;
|
||||
|
||||
struct _CoglGpuInfo
|
||||
{
|
||||
CoglGpuInfoVendor vendor;
|
||||
const char *vendor_name;
|
||||
|
||||
CoglGpuInfoDriverPackage driver_package;
|
||||
const char *driver_package_name;
|
||||
int driver_package_version;
|
||||
|
||||
CoglGpuInfoArchitecture architecture;
|
||||
const char *architecture_name;
|
||||
CoglGpuInfoArchitectureFlag architecture_flags;
|
||||
|
||||
CoglGpuInfoDriverBug driver_bugs;
|
||||
};
|
||||
|
||||
/*
|
||||
* _cogl_gpu_info_init:
|
||||
* @ctx: A #CoglContext
|
||||
* @gpu: A return location for the GPU information
|
||||
*
|
||||
* Determines information about the GPU and driver from the given
|
||||
* context.
|
||||
*/
|
||||
void
|
||||
_cogl_gpu_info_init (CoglContext *ctx,
|
||||
CoglGpuInfo *gpu);
|
||||
|
||||
#endif /* __COGL_GPU_INFO_PRIVATE_H */
|
@@ -1,572 +0,0 @@
|
||||
/*
|
||||
* Cogl
|
||||
*
|
||||
* A Low Level GPU Graphics and Utilities API
|
||||
*
|
||||
* Copyright (C) 2012 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 <errno.h>
|
||||
|
||||
#include <test-fixtures/test-unit.h>
|
||||
|
||||
#include "cogl-gpu-info-private.h"
|
||||
#include "cogl-context-private.h"
|
||||
#include "cogl-version.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char *renderer_string;
|
||||
const char *version_string;
|
||||
const char *vendor_string;
|
||||
} CoglGpuInfoStrings;
|
||||
|
||||
typedef struct CoglGpuInfoArchitectureDescription
|
||||
{
|
||||
CoglGpuInfoArchitecture architecture;
|
||||
const char *name;
|
||||
CoglGpuInfoArchitectureFlag flags;
|
||||
gboolean (* check_function) (const CoglGpuInfoStrings *strings);
|
||||
|
||||
} CoglGpuInfoArchitectureDescription;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CoglGpuInfoVendor vendor;
|
||||
const char *name;
|
||||
gboolean (* check_function) (const CoglGpuInfoStrings *strings);
|
||||
const CoglGpuInfoArchitectureDescription *architectures;
|
||||
|
||||
} CoglGpuInfoVendorDescription;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CoglGpuInfoDriverPackage driver_package;
|
||||
const char *name;
|
||||
gboolean (* check_function) (const CoglGpuInfoStrings *strings,
|
||||
int *version_out);
|
||||
} CoglGpuInfoDriverPackageDescription;
|
||||
|
||||
static gboolean
|
||||
_cogl_gpu_info_parse_version_string (const char *version_string,
|
||||
int n_components,
|
||||
const char **tail,
|
||||
int *version_ret)
|
||||
{
|
||||
int version = 0;
|
||||
uint64_t part;
|
||||
int i;
|
||||
|
||||
for (i = 0; ; i++)
|
||||
{
|
||||
errno = 0;
|
||||
part = g_ascii_strtoull (version_string,
|
||||
(char **) &version_string,
|
||||
10);
|
||||
|
||||
if (errno || part > COGL_VERSION_MAX_COMPONENT_VALUE)
|
||||
return FALSE;
|
||||
|
||||
version |= part << ((2 - i) * COGL_VERSION_COMPONENT_BITS);
|
||||
|
||||
if (i + 1 >= n_components)
|
||||
break;
|
||||
|
||||
if (*version_string != '.')
|
||||
return FALSE;
|
||||
|
||||
version_string++;
|
||||
}
|
||||
|
||||
if (version_ret)
|
||||
*version_ret = version;
|
||||
if (tail)
|
||||
*tail = version_string;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
match_phrase (const char *string, const char *phrase)
|
||||
{
|
||||
const char *part = strstr (string, phrase);
|
||||
int len;
|
||||
|
||||
if (part == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* The match must either be at the beginning of the string or
|
||||
preceded by a space. */
|
||||
if (part > string && part[-1] != ' ')
|
||||
return FALSE;
|
||||
|
||||
/* Also match must either be at end of string or followed by a
|
||||
* space. */
|
||||
len = strlen (phrase);
|
||||
if (part[len] != '\0' && part[len] != ' ')
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_intel_vendor (const CoglGpuInfoStrings *strings)
|
||||
{
|
||||
return match_phrase (strings->renderer_string, "Intel(R)");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_imagination_technologies_vendor (const CoglGpuInfoStrings *strings)
|
||||
{
|
||||
if (strcmp (strings->vendor_string, "Imagination Technologies") != 0)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_arm_vendor (const CoglGpuInfoStrings *strings)
|
||||
{
|
||||
if (strcmp (strings->vendor_string, "ARM") != 0)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_qualcomm_vendor (const CoglGpuInfoStrings *strings)
|
||||
{
|
||||
if (strcmp (strings->vendor_string, "Qualcomm") != 0)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_nvidia_vendor (const CoglGpuInfoStrings *strings)
|
||||
{
|
||||
if (strcmp (strings->vendor_string, "NVIDIA") != 0 &&
|
||||
strcmp (strings->vendor_string, "NVIDIA Corporation") != 0)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_ati_vendor (const CoglGpuInfoStrings *strings)
|
||||
{
|
||||
if (strcmp (strings->vendor_string, "ATI") != 0)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_mesa_vendor (const CoglGpuInfoStrings *strings)
|
||||
{
|
||||
if (strcmp (strings->vendor_string, "Tungsten Graphics, Inc") == 0)
|
||||
return TRUE;
|
||||
else if (strcmp (strings->vendor_string, "VMware, Inc.") == 0)
|
||||
return TRUE;
|
||||
else if (strcmp (strings->vendor_string, "Mesa Project") == 0)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_true (const CoglGpuInfoStrings *strings)
|
||||
{
|
||||
/* This is a last resort so it always matches */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_sandybridge_architecture (const CoglGpuInfoStrings *strings)
|
||||
{
|
||||
return match_phrase (strings->renderer_string, "Sandybridge");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_llvmpipe_architecture (const CoglGpuInfoStrings *strings)
|
||||
{
|
||||
return match_phrase (strings->renderer_string, "llvmpipe");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_softpipe_architecture (const CoglGpuInfoStrings *strings)
|
||||
{
|
||||
return match_phrase (strings->renderer_string, "softpipe");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_swrast_architecture (const CoglGpuInfoStrings *strings)
|
||||
{
|
||||
return match_phrase (strings->renderer_string, "software rasterizer") ||
|
||||
match_phrase (strings->renderer_string, "Software Rasterizer");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_sgx_architecture (const CoglGpuInfoStrings *strings)
|
||||
{
|
||||
if (strncmp (strings->renderer_string, "PowerVR SGX", 12) != 0)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_mali_architecture (const CoglGpuInfoStrings *strings)
|
||||
{
|
||||
if (strncmp (strings->renderer_string, "Mali-", 5) != 0)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const CoglGpuInfoArchitectureDescription
|
||||
intel_architectures[] =
|
||||
{
|
||||
{
|
||||
COGL_GPU_INFO_ARCHITECTURE_SANDYBRIDGE,
|
||||
"Sandybridge",
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_IMMEDIATE_MODE |
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_IMMEDIATE_MODE,
|
||||
check_sandybridge_architecture
|
||||
},
|
||||
{
|
||||
COGL_GPU_INFO_ARCHITECTURE_UNKNOWN,
|
||||
"Unknown",
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_IMMEDIATE_MODE |
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_IMMEDIATE_MODE,
|
||||
check_true
|
||||
}
|
||||
};
|
||||
|
||||
static const CoglGpuInfoArchitectureDescription
|
||||
powervr_architectures[] =
|
||||
{
|
||||
{
|
||||
COGL_GPU_INFO_ARCHITECTURE_SGX,
|
||||
"SGX",
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_TILED |
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_DEFERRED,
|
||||
check_sgx_architecture
|
||||
},
|
||||
{
|
||||
COGL_GPU_INFO_ARCHITECTURE_UNKNOWN,
|
||||
"Unknown",
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_TILED |
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_TILED,
|
||||
check_true
|
||||
}
|
||||
};
|
||||
|
||||
static const CoglGpuInfoArchitectureDescription
|
||||
arm_architectures[] =
|
||||
{
|
||||
{
|
||||
COGL_GPU_INFO_ARCHITECTURE_MALI,
|
||||
"Mali",
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_TILED |
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_IMMEDIATE_MODE,
|
||||
check_mali_architecture
|
||||
},
|
||||
{
|
||||
COGL_GPU_INFO_ARCHITECTURE_UNKNOWN,
|
||||
"Unknown",
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_TILED |
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_IMMEDIATE_MODE,
|
||||
check_true
|
||||
}
|
||||
};
|
||||
|
||||
static const CoglGpuInfoArchitectureDescription
|
||||
mesa_architectures[] =
|
||||
{
|
||||
{
|
||||
COGL_GPU_INFO_ARCHITECTURE_LLVMPIPE,
|
||||
"LLVM Pipe",
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_IMMEDIATE_MODE |
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_SOFTWARE |
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_IMMEDIATE_MODE |
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_SOFTWARE,
|
||||
check_llvmpipe_architecture
|
||||
},
|
||||
{
|
||||
COGL_GPU_INFO_ARCHITECTURE_SOFTPIPE,
|
||||
"Softpipe",
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_IMMEDIATE_MODE |
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_SOFTWARE |
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_IMMEDIATE_MODE |
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_SOFTWARE,
|
||||
check_softpipe_architecture
|
||||
},
|
||||
{
|
||||
COGL_GPU_INFO_ARCHITECTURE_SWRAST,
|
||||
"SWRast",
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_IMMEDIATE_MODE |
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_SOFTWARE |
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_IMMEDIATE_MODE |
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_SOFTWARE,
|
||||
check_swrast_architecture
|
||||
},
|
||||
{
|
||||
COGL_GPU_INFO_ARCHITECTURE_UNKNOWN,
|
||||
"Unknown",
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_IMMEDIATE_MODE |
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_IMMEDIATE_MODE,
|
||||
check_true
|
||||
}
|
||||
};
|
||||
|
||||
static const CoglGpuInfoArchitectureDescription
|
||||
unknown_architectures[] =
|
||||
{
|
||||
{
|
||||
COGL_GPU_INFO_ARCHITECTURE_UNKNOWN,
|
||||
"Unknown",
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_IMMEDIATE_MODE |
|
||||
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_IMMEDIATE_MODE,
|
||||
check_true
|
||||
}
|
||||
};
|
||||
|
||||
static const CoglGpuInfoVendorDescription
|
||||
_cogl_gpu_info_vendors[] =
|
||||
{
|
||||
{
|
||||
COGL_GPU_INFO_VENDOR_INTEL,
|
||||
"Intel",
|
||||
check_intel_vendor,
|
||||
intel_architectures
|
||||
},
|
||||
{
|
||||
COGL_GPU_INFO_VENDOR_IMAGINATION_TECHNOLOGIES,
|
||||
"Imagination Technologies",
|
||||
check_imagination_technologies_vendor,
|
||||
powervr_architectures
|
||||
},
|
||||
{
|
||||
COGL_GPU_INFO_VENDOR_ARM,
|
||||
"ARM",
|
||||
check_arm_vendor,
|
||||
arm_architectures
|
||||
},
|
||||
{
|
||||
COGL_GPU_INFO_VENDOR_QUALCOMM,
|
||||
"Qualcomm",
|
||||
check_qualcomm_vendor,
|
||||
unknown_architectures
|
||||
},
|
||||
{
|
||||
COGL_GPU_INFO_VENDOR_NVIDIA,
|
||||
"Nvidia",
|
||||
check_nvidia_vendor,
|
||||
unknown_architectures
|
||||
},
|
||||
{
|
||||
COGL_GPU_INFO_VENDOR_ATI,
|
||||
"ATI",
|
||||
check_ati_vendor,
|
||||
unknown_architectures
|
||||
},
|
||||
/* Must be last */
|
||||
{
|
||||
COGL_GPU_INFO_VENDOR_MESA,
|
||||
"Mesa",
|
||||
check_mesa_vendor,
|
||||
mesa_architectures
|
||||
},
|
||||
{
|
||||
COGL_GPU_INFO_VENDOR_UNKNOWN,
|
||||
"Unknown",
|
||||
check_true,
|
||||
unknown_architectures
|
||||
}
|
||||
};
|
||||
|
||||
static gboolean
|
||||
check_mesa_driver_package (const CoglGpuInfoStrings *strings,
|
||||
int *version_ret)
|
||||
{
|
||||
uint64_t micro_part;
|
||||
const char *v;
|
||||
|
||||
/* The version string should always begin a two-part GL version
|
||||
number */
|
||||
if (!_cogl_gpu_info_parse_version_string (strings->version_string,
|
||||
2, /* n_components */
|
||||
&v, /* tail */
|
||||
NULL /* version_ret */))
|
||||
return FALSE;
|
||||
|
||||
/* In mesa this will be followed optionally by "(Core Profile)" and
|
||||
* then "Mesa" */
|
||||
v = strstr (v, " Mesa ");
|
||||
if (!v)
|
||||
return FALSE;
|
||||
|
||||
v += 6;
|
||||
|
||||
/* Next there will be a version string that is at least two
|
||||
components. On a git devel build the version will be something
|
||||
like "-devel<git hash>" instead */
|
||||
if (!_cogl_gpu_info_parse_version_string (v,
|
||||
2, /* n_components */
|
||||
&v, /* tail */
|
||||
version_ret))
|
||||
return FALSE;
|
||||
|
||||
/* If it is a development build then we'll just leave the micro
|
||||
number as 0 */
|
||||
if (g_str_has_prefix (v, "-devel"))
|
||||
return TRUE;
|
||||
|
||||
/* Otherwise there should be a micro version number */
|
||||
if (*v != '.')
|
||||
return FALSE;
|
||||
|
||||
errno = 0;
|
||||
micro_part = g_ascii_strtoull (v + 1, NULL /* endptr */, 10 /* base */);
|
||||
if (errno || micro_part > COGL_VERSION_MAX_COMPONENT_VALUE)
|
||||
return FALSE;
|
||||
|
||||
*version_ret = COGL_VERSION_ENCODE (COGL_VERSION_GET_MAJOR (*version_ret),
|
||||
COGL_VERSION_GET_MINOR (*version_ret),
|
||||
micro_part);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
UNIT_TEST (check_mesa_driver_package_parser,
|
||||
0, /* no requirements */
|
||||
0 /* no failure cases */)
|
||||
{
|
||||
/* renderer_string, version_string, vendor_string;*/
|
||||
const CoglGpuInfoStrings test_strings[2] = {
|
||||
{ NULL, "3.1 Mesa 9.2-devel15436ad", NULL },
|
||||
{ NULL, "3.1 (Core Profile) Mesa 9.2.0-devel (git-15436ad)", NULL }
|
||||
};
|
||||
int i;
|
||||
int version;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (test_strings); i++)
|
||||
{
|
||||
g_assert (check_mesa_driver_package (&test_strings[i], &version));
|
||||
g_assert_cmpint (version, ==, COGL_VERSION_ENCODE (9, 2, 0));
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_unknown_driver_package (const CoglGpuInfoStrings *strings,
|
||||
int *version_out)
|
||||
{
|
||||
*version_out = 0;
|
||||
|
||||
/* This is a last resort so it always matches */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const CoglGpuInfoDriverPackageDescription
|
||||
_cogl_gpu_info_driver_packages[] =
|
||||
{
|
||||
{
|
||||
COGL_GPU_INFO_DRIVER_PACKAGE_MESA,
|
||||
"Mesa",
|
||||
check_mesa_driver_package
|
||||
},
|
||||
/* Must be last */
|
||||
{
|
||||
COGL_GPU_INFO_DRIVER_PACKAGE_UNKNOWN,
|
||||
"Unknown",
|
||||
check_unknown_driver_package
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
_cogl_gpu_info_init (CoglContext *ctx,
|
||||
CoglGpuInfo *gpu)
|
||||
{
|
||||
CoglGpuInfoStrings strings;
|
||||
int i;
|
||||
|
||||
strings.renderer_string = (const char *) ctx->glGetString (GL_RENDERER);
|
||||
strings.version_string = _cogl_context_get_gl_version (ctx);
|
||||
strings.vendor_string = (const char *) ctx->glGetString (GL_VENDOR);
|
||||
|
||||
/* Determine the driver package */
|
||||
for (i = 0; ; i++)
|
||||
{
|
||||
const CoglGpuInfoDriverPackageDescription *description =
|
||||
_cogl_gpu_info_driver_packages + i;
|
||||
|
||||
if (description->check_function (&strings, &gpu->driver_package_version))
|
||||
{
|
||||
gpu->driver_package = description->driver_package;
|
||||
gpu->driver_package_name = description->name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine the GPU vendor */
|
||||
for (i = 0; ; i++)
|
||||
{
|
||||
const CoglGpuInfoVendorDescription *description =
|
||||
_cogl_gpu_info_vendors + i;
|
||||
|
||||
if (description->check_function (&strings))
|
||||
{
|
||||
int j;
|
||||
|
||||
gpu->vendor = description->vendor;
|
||||
gpu->vendor_name = description->name;
|
||||
|
||||
for (j = 0; ; j++)
|
||||
{
|
||||
const CoglGpuInfoArchitectureDescription *architecture =
|
||||
description->architectures + j;
|
||||
|
||||
if (architecture->check_function (&strings))
|
||||
{
|
||||
gpu->architecture = architecture->architecture;
|
||||
gpu->architecture_name = architecture->name;
|
||||
gpu->architecture_flags = architecture->flags;
|
||||
goto probed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
probed:
|
||||
|
||||
COGL_NOTE (WINSYS, "Driver package = %s, vendor = %s, architecture = %s\n",
|
||||
gpu->driver_package_name,
|
||||
gpu->vendor_name,
|
||||
gpu->architecture_name);
|
||||
|
||||
/* Determine the driver bugs */
|
||||
gpu->driver_bugs = 0;
|
||||
}
|
@@ -41,7 +41,6 @@
|
||||
#include "cogl-matrix-private.h"
|
||||
#include "cogl-magazine-private.h"
|
||||
#include "cogl-gtype-private.h"
|
||||
#include "driver/gl/cogl-util-gl-private.h"
|
||||
|
||||
static void _cogl_matrix_stack_free (CoglMatrixStack *stack);
|
||||
|
||||
|
@@ -44,7 +44,6 @@
|
||||
#include "cogl-node-private.h"
|
||||
#include "cogl-context-private.h"
|
||||
#include "cogl-texture-private.h"
|
||||
#include "driver/gl/cogl-pipeline-opengl-private.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -342,8 +341,6 @@ _cogl_pipeline_layer_pre_change_notify (CoglPipeline *required_owner,
|
||||
CoglPipelineLayer *layer,
|
||||
CoglPipelineLayerState change)
|
||||
{
|
||||
CoglTextureUnit *unit;
|
||||
|
||||
/* Identify the case where the layer is new with no owner or
|
||||
* dependants and so we don't need to do anything. */
|
||||
if (_cogl_list_empty (&COGL_NODE (layer)->children) &&
|
||||
@@ -403,15 +400,6 @@ _cogl_pipeline_layer_pre_change_notify (CoglPipeline *required_owner,
|
||||
progend->layer_pre_change_notify (required_owner, layer, change);
|
||||
}
|
||||
|
||||
/* If the layer being changed is the same as the last layer we
|
||||
* flushed to the corresponding texture unit then we keep a track of
|
||||
* the changes so we can try to minimize redundant OpenGL calls if
|
||||
* the same layer is flushed again.
|
||||
*/
|
||||
unit = _cogl_get_texture_unit (_cogl_pipeline_layer_get_unit_index (layer));
|
||||
if (unit->layer == layer)
|
||||
unit->layer_changes_since_flush |= change;
|
||||
|
||||
init_layer_state:
|
||||
|
||||
if (required_owner)
|
||||
|
@@ -51,22 +51,6 @@
|
||||
#include "cogl-pixel-buffer.h"
|
||||
#include "cogl-gtype-private.h"
|
||||
|
||||
/*
|
||||
* GL/GLES compatibility defines for the buffer API:
|
||||
*/
|
||||
|
||||
#if defined (HAVE_COGL_GL)
|
||||
|
||||
#ifndef GL_PIXEL_UNPACK_BUFFER
|
||||
#define GL_PIXEL_UNPACK_BUFFER GL_PIXEL_UNPACK_BUFFER_ARB
|
||||
#endif
|
||||
|
||||
#ifndef GL_PIXEL_PACK_BUFFER
|
||||
#define GL_PIXEL_PACK_BUFFER GL_PIXEL_PACK_BUFFER_ARB
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
_cogl_pixel_buffer_free (CoglPixelBuffer *buffer);
|
||||
|
||||
|
@@ -34,11 +34,6 @@
|
||||
|
||||
#include "cogl-sampler-cache-private.h"
|
||||
#include "cogl-context-private.h"
|
||||
#include "driver/gl/cogl-util-gl-private.h"
|
||||
|
||||
#ifndef GL_TEXTURE_WRAP_R
|
||||
#define GL_TEXTURE_WRAP_R 0x8072
|
||||
#endif
|
||||
|
||||
struct _CoglSamplerCache
|
||||
{
|
||||
@@ -54,10 +49,6 @@ struct _CoglSamplerCache
|
||||
GL state. */
|
||||
GHashTable *hash_table_cogl;
|
||||
GHashTable *hash_table_gl;
|
||||
|
||||
/* This is used for generated fake unique sampler object numbers
|
||||
when the sampler object extension is not supported */
|
||||
GLuint next_fake_sampler_object_number;
|
||||
};
|
||||
|
||||
static CoglSamplerCacheWrapMode
|
||||
@@ -176,22 +167,10 @@ _cogl_sampler_cache_new (CoglContext *context)
|
||||
sampler_state_equal_gl);
|
||||
cache->hash_table_cogl = g_hash_table_new (hash_sampler_state_cogl,
|
||||
sampler_state_equal_cogl);
|
||||
cache->next_fake_sampler_object_number = 1;
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
static void
|
||||
set_wrap_mode (CoglContext *context,
|
||||
GLuint sampler_object,
|
||||
GLenum param,
|
||||
CoglSamplerCacheWrapMode wrap_mode)
|
||||
{
|
||||
GE( context, glSamplerParameteri (sampler_object,
|
||||
param,
|
||||
wrap_mode) );
|
||||
}
|
||||
|
||||
static CoglSamplerCacheEntry *
|
||||
_cogl_sampler_cache_get_entry_gl (CoglSamplerCache *cache,
|
||||
const CoglSamplerCacheEntry *key)
|
||||
@@ -202,39 +181,9 @@ _cogl_sampler_cache_get_entry_gl (CoglSamplerCache *cache,
|
||||
|
||||
if (entry == NULL)
|
||||
{
|
||||
CoglContext *context = cache->context;
|
||||
|
||||
entry = g_slice_dup (CoglSamplerCacheEntry, key);
|
||||
|
||||
if (_cogl_has_private_feature (context,
|
||||
COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS))
|
||||
{
|
||||
GE( context, glGenSamplers (1, &entry->sampler_object) );
|
||||
|
||||
GE( context, glSamplerParameteri (entry->sampler_object,
|
||||
GL_TEXTURE_MIN_FILTER,
|
||||
entry->min_filter) );
|
||||
GE( context, glSamplerParameteri (entry->sampler_object,
|
||||
GL_TEXTURE_MAG_FILTER,
|
||||
entry->mag_filter) );
|
||||
|
||||
set_wrap_mode (context,
|
||||
entry->sampler_object,
|
||||
GL_TEXTURE_WRAP_S,
|
||||
entry->wrap_mode_s);
|
||||
set_wrap_mode (context,
|
||||
entry->sampler_object,
|
||||
GL_TEXTURE_WRAP_T,
|
||||
entry->wrap_mode_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If sampler objects aren't supported then we'll invent a
|
||||
unique number so that pipelines can still compare the
|
||||
unique state just by comparing the sampler object
|
||||
numbers */
|
||||
entry->sampler_object = cache->next_fake_sampler_object_number++;
|
||||
}
|
||||
cache->context->driver_vtable->sampler_init (cache->context, entry);
|
||||
|
||||
g_hash_table_insert (cache->hash_table_gl, entry, entry);
|
||||
}
|
||||
@@ -320,9 +269,7 @@ hash_table_free_gl_cb (void *key,
|
||||
CoglContext *context = user_data;
|
||||
CoglSamplerCacheEntry *entry = value;
|
||||
|
||||
if (_cogl_has_private_feature (context,
|
||||
COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS))
|
||||
GE( context, glDeleteSamplers (1, &entry->sampler_object) );
|
||||
context->driver_vtable->sampler_free (context, entry);
|
||||
|
||||
g_slice_free (CoglSamplerCacheEntry, entry);
|
||||
}
|
||||
|
@@ -62,11 +62,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
/* This isn't defined in the GLES headers */
|
||||
#ifndef GL_RED
|
||||
#define GL_RED 0x1903
|
||||
#endif
|
||||
|
||||
COGL_GTYPE_DEFINE_INTERFACE (Texture, texture);
|
||||
|
||||
uint32_t
|
||||
@@ -786,8 +781,6 @@ cogl_texture_get_data (CoglTexture *texture,
|
||||
if (texture_format == COGL_PIXEL_FORMAT_A_8)
|
||||
{
|
||||
closest_format = COGL_PIXEL_FORMAT_A_8;
|
||||
closest_gl_format = GL_RED;
|
||||
closest_gl_type = GL_UNSIGNED_BYTE;
|
||||
}
|
||||
else if (format == COGL_PIXEL_FORMAT_A_8)
|
||||
{
|
||||
@@ -798,8 +791,6 @@ cogl_texture_get_data (CoglTexture *texture,
|
||||
* pre-multiplied here because we're only going to look at
|
||||
* the alpha component */
|
||||
closest_format = COGL_PIXEL_FORMAT_RGBA_8888;
|
||||
closest_gl_format = GL_RGBA;
|
||||
closest_gl_type = GL_UNSIGNED_BYTE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -31,7 +31,6 @@
|
||||
#include "cogl-config.h"
|
||||
|
||||
#include "cogl-util.h"
|
||||
#include "driver/gl/cogl-util-gl-private.h"
|
||||
#include "cogl-context-private.h"
|
||||
#include "cogl-object-private.h"
|
||||
|
||||
|
@@ -47,16 +47,4 @@ struct _CoglShader
|
||||
char *source;
|
||||
};
|
||||
|
||||
void
|
||||
_cogl_shader_compile_real (CoglHandle handle,
|
||||
CoglPipeline *pipeline);
|
||||
|
||||
void
|
||||
_cogl_shader_set_source_with_boilerplate (GLuint shader_gl_handle,
|
||||
GLenum shader_gl_type,
|
||||
int n_tex_coord_attribs,
|
||||
GLsizei count_in,
|
||||
const char **strings_in,
|
||||
const GLint *lengths_in);
|
||||
|
||||
#endif /* __COGL_SHADER_H */
|
||||
|
@@ -32,7 +32,6 @@
|
||||
|
||||
#include "cogl-context-private.h"
|
||||
#include "cogl-object-private.h"
|
||||
#include "cogl-glsl-shader-private.h"
|
||||
#include "cogl-glsl-shader-boilerplate.h"
|
||||
#include "driver/gl/cogl-util-gl-private.h"
|
||||
#include "deprecated/cogl-shader-private.h"
|
||||
@@ -45,13 +44,6 @@ static void _cogl_shader_free (CoglShader *shader);
|
||||
|
||||
COGL_HANDLE_DEFINE (Shader, shader);
|
||||
|
||||
#ifndef GL_FRAGMENT_SHADER
|
||||
#define GL_FRAGMENT_SHADER 0x8B30
|
||||
#endif
|
||||
#ifndef GL_VERTEX_SHADER
|
||||
#define GL_VERTEX_SHADER 0x8B31
|
||||
#endif
|
||||
|
||||
static void
|
||||
_cogl_shader_free (CoglShader *shader)
|
||||
{
|
||||
@@ -91,23 +83,6 @@ cogl_create_shader (CoglShaderType type)
|
||||
return _cogl_shader_handle_new (shader);
|
||||
}
|
||||
|
||||
static void
|
||||
delete_shader (CoglShader *shader)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
if (shader->gl_handle)
|
||||
GE (ctx, glDeleteShader (shader->gl_handle));
|
||||
|
||||
shader->gl_handle = 0;
|
||||
|
||||
if (shader->compilation_pipeline)
|
||||
{
|
||||
cogl_object_unref (shader->compilation_pipeline);
|
||||
shader->compilation_pipeline = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cogl_shader_source (CoglHandle handle,
|
||||
const char *source)
|
||||
@@ -124,77 +99,6 @@ cogl_shader_source (CoglHandle handle,
|
||||
shader->source = g_strdup (source);
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_shader_compile_real (CoglHandle handle,
|
||||
CoglPipeline *pipeline)
|
||||
{
|
||||
CoglShader *shader = handle;
|
||||
GLenum gl_type;
|
||||
GLint status;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
if (shader->gl_handle)
|
||||
{
|
||||
CoglPipeline *prev = shader->compilation_pipeline;
|
||||
|
||||
/* XXX: currently the only things that will affect the
|
||||
* boilerplate for user shaders, apart from driver features,
|
||||
* are the pipeline layer-indices and texture-unit-indices
|
||||
*/
|
||||
if (pipeline == prev ||
|
||||
_cogl_pipeline_layer_and_unit_numbers_equal (prev, pipeline))
|
||||
return;
|
||||
}
|
||||
|
||||
if (shader->gl_handle)
|
||||
delete_shader (shader);
|
||||
|
||||
switch (shader->type)
|
||||
{
|
||||
case COGL_SHADER_TYPE_VERTEX:
|
||||
gl_type = GL_VERTEX_SHADER;
|
||||
break;
|
||||
case COGL_SHADER_TYPE_FRAGMENT:
|
||||
gl_type = GL_FRAGMENT_SHADER;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
shader->gl_handle = ctx->glCreateShader (gl_type);
|
||||
|
||||
_cogl_glsl_shader_set_source_with_boilerplate (ctx,
|
||||
shader->gl_handle,
|
||||
gl_type,
|
||||
pipeline,
|
||||
1,
|
||||
(const char **)
|
||||
&shader->source,
|
||||
NULL);
|
||||
|
||||
GE (ctx, glCompileShader (shader->gl_handle));
|
||||
|
||||
shader->compilation_pipeline = cogl_object_ref (pipeline);
|
||||
|
||||
GE (ctx, glGetShaderiv (shader->gl_handle, GL_COMPILE_STATUS, &status));
|
||||
if (!status)
|
||||
{
|
||||
char buffer[512];
|
||||
int len = 0;
|
||||
|
||||
ctx->glGetShaderInfoLog (shader->gl_handle, 511, &len, buffer);
|
||||
buffer[len] = '\0';
|
||||
|
||||
g_warning ("Failed to compile GLSL program:\n"
|
||||
"src:\n%s\n"
|
||||
"error:\n%s\n",
|
||||
shader->source,
|
||||
buffer);
|
||||
}
|
||||
}
|
||||
|
||||
CoglShaderType
|
||||
cogl_shader_get_type (CoglHandle handle)
|
||||
{
|
||||
|
@@ -43,11 +43,11 @@
|
||||
#include "cogl-snippet-private.h"
|
||||
#include "cogl-list.h"
|
||||
#include "driver/gl/cogl-util-gl-private.h"
|
||||
#include "driver/gl/cogl-pipeline-opengl-private.h"
|
||||
|
||||
#include "cogl-context-private.h"
|
||||
#include "cogl-object-private.h"
|
||||
#include "cogl-pipeline-cache.h"
|
||||
#include "cogl-glsl-shader-private.h"
|
||||
#include "driver/gl/cogl-pipeline-fragend-glsl-private.h"
|
||||
#include "deprecated/cogl-shader-private.h"
|
||||
#include "deprecated/cogl-program-private.h"
|
||||
|
@@ -146,5 +146,27 @@ _cogl_pipeline_flush_gl_state (CoglContext *context,
|
||||
gboolean skip_gl_state,
|
||||
gboolean unknown_color_alpha);
|
||||
|
||||
void
|
||||
_cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
|
||||
GLuint shader_gl_handle,
|
||||
GLenum shader_gl_type,
|
||||
CoglPipeline *pipeline,
|
||||
GLsizei count_in,
|
||||
const char **strings_in,
|
||||
const GLint *lengths_in);
|
||||
|
||||
void
|
||||
_cogl_sampler_gl_init (CoglContext *context,
|
||||
CoglSamplerCacheEntry *entry);
|
||||
|
||||
void
|
||||
_cogl_sampler_gl_free (CoglContext *context,
|
||||
CoglSamplerCacheEntry *entry);
|
||||
|
||||
void
|
||||
_cogl_gl_set_uniform (CoglContext *ctx,
|
||||
GLint location,
|
||||
const CoglBoxedValue *value);
|
||||
|
||||
#endif /* __COGL_PIPELINE_OPENGL_PRIVATE_H */
|
||||
|
||||
|
@@ -94,47 +94,51 @@ CoglTextureUnit *
|
||||
_cogl_get_texture_unit (int index_)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, NULL);
|
||||
CoglGLContext *glctx = _cogl_driver_gl_context(ctx);
|
||||
|
||||
if (ctx->texture_units->len < (index_ + 1))
|
||||
if (glctx->texture_units->len < (index_ + 1))
|
||||
{
|
||||
int i;
|
||||
int prev_len = ctx->texture_units->len;
|
||||
ctx->texture_units = g_array_set_size (ctx->texture_units, index_ + 1);
|
||||
int prev_len = glctx->texture_units->len;
|
||||
glctx->texture_units = g_array_set_size (glctx->texture_units,
|
||||
index_ + 1);
|
||||
for (i = prev_len; i <= index_; i++)
|
||||
{
|
||||
CoglTextureUnit *unit =
|
||||
&g_array_index (ctx->texture_units, CoglTextureUnit, i);
|
||||
&g_array_index (glctx->texture_units, CoglTextureUnit, i);
|
||||
|
||||
texture_unit_init (ctx, unit, i);
|
||||
}
|
||||
}
|
||||
|
||||
return &g_array_index (ctx->texture_units, CoglTextureUnit, index_);
|
||||
return &g_array_index (glctx->texture_units, CoglTextureUnit, index_);
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_destroy_texture_units (CoglContext *ctx)
|
||||
{
|
||||
int i;
|
||||
CoglGLContext *glctx = _cogl_driver_gl_context(ctx);
|
||||
|
||||
for (i = 0; i < ctx->texture_units->len; i++)
|
||||
for (i = 0; i < glctx->texture_units->len; i++)
|
||||
{
|
||||
CoglTextureUnit *unit =
|
||||
&g_array_index (ctx->texture_units, CoglTextureUnit, i);
|
||||
&g_array_index (glctx->texture_units, CoglTextureUnit, i);
|
||||
texture_unit_free (unit);
|
||||
}
|
||||
g_array_free (ctx->texture_units, TRUE);
|
||||
g_array_free (glctx->texture_units, TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_set_active_texture_unit (int unit_index)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
CoglGLContext *glctx = _cogl_driver_gl_context(ctx);
|
||||
|
||||
if (ctx->active_texture_unit != unit_index)
|
||||
if (glctx->active_texture_unit != unit_index)
|
||||
{
|
||||
GE (ctx, glActiveTexture (GL_TEXTURE0 + unit_index));
|
||||
ctx->active_texture_unit = unit_index;
|
||||
glctx->active_texture_unit = unit_index;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,11 +194,12 @@ _cogl_delete_gl_texture (GLuint gl_texture)
|
||||
int i;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
CoglGLContext *glctx = _cogl_driver_gl_context(ctx);
|
||||
|
||||
for (i = 0; i < ctx->texture_units->len; i++)
|
||||
for (i = 0; i < glctx->texture_units->len; i++)
|
||||
{
|
||||
CoglTextureUnit *unit =
|
||||
&g_array_index (ctx->texture_units, CoglTextureUnit, i);
|
||||
&g_array_index (glctx->texture_units, CoglTextureUnit, i);
|
||||
|
||||
if (unit->gl_texture == gl_texture)
|
||||
{
|
||||
@@ -218,11 +223,12 @@ _cogl_pipeline_texture_storage_change_notify (CoglTexture *texture)
|
||||
int i;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
CoglGLContext *glctx = _cogl_driver_gl_context(ctx);
|
||||
|
||||
for (i = 0; i < ctx->texture_units->len; i++)
|
||||
for (i = 0; i < glctx->texture_units->len; i++)
|
||||
{
|
||||
CoglTextureUnit *unit =
|
||||
&g_array_index (ctx->texture_units, CoglTextureUnit, i);
|
||||
&g_array_index (glctx->texture_units, CoglTextureUnit, i);
|
||||
|
||||
if (unit->layer &&
|
||||
_cogl_pipeline_layer_get_texture (unit->layer) == texture)
|
||||
@@ -688,6 +694,48 @@ _cogl_pipeline_layer_forward_wrap_modes (CoglPipelineLayer *layer,
|
||||
gl_wrap_mode_t);
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_sampler_gl_init (CoglContext *context, CoglSamplerCacheEntry *entry)
|
||||
{
|
||||
if (_cogl_has_private_feature (context,
|
||||
COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS))
|
||||
{
|
||||
GE( context, glGenSamplers (1, &entry->sampler_object) );
|
||||
|
||||
GE( context, glSamplerParameteri (entry->sampler_object,
|
||||
GL_TEXTURE_MIN_FILTER,
|
||||
entry->min_filter) );
|
||||
GE( context, glSamplerParameteri (entry->sampler_object,
|
||||
GL_TEXTURE_MAG_FILTER,
|
||||
entry->mag_filter) );
|
||||
|
||||
GE (context, glSamplerParameteri (entry->sampler_object,
|
||||
GL_TEXTURE_WRAP_S,
|
||||
entry->wrap_mode_s) );
|
||||
GE (context, glSamplerParameteri (entry->sampler_object,
|
||||
GL_TEXTURE_WRAP_T,
|
||||
entry->wrap_mode_t) );
|
||||
}
|
||||
else
|
||||
{
|
||||
CoglGLContext *gl_context = context->driver_context;
|
||||
|
||||
/* If sampler objects aren't supported then we'll invent a
|
||||
unique number so that pipelines can still compare the
|
||||
unique state just by comparing the sampler object
|
||||
numbers */
|
||||
entry->sampler_object = gl_context->next_fake_sampler_object_number++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_sampler_gl_free (CoglContext *context, CoglSamplerCacheEntry *entry)
|
||||
{
|
||||
if (_cogl_has_private_feature (context,
|
||||
COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS))
|
||||
GE( context, glDeleteSamplers (1, &entry->sampler_object) );
|
||||
}
|
||||
|
||||
/* OpenGL associates the min/mag filters and repeat modes with the
|
||||
* texture object not the texture unit so we always have to re-assert
|
||||
* the filter and repeat modes whenever we use a texture since it may
|
||||
@@ -704,11 +752,12 @@ foreach_texture_unit_update_filter_and_wrap_modes (void)
|
||||
int i;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
CoglGLContext *glctx = _cogl_driver_gl_context(ctx);
|
||||
|
||||
for (i = 0; i < ctx->texture_units->len; i++)
|
||||
for (i = 0; i < glctx->texture_units->len; i++)
|
||||
{
|
||||
CoglTextureUnit *unit =
|
||||
&g_array_index (ctx->texture_units, CoglTextureUnit, i);
|
||||
&g_array_index (glctx->texture_units, CoglTextureUnit, i);
|
||||
|
||||
if (unit->layer)
|
||||
{
|
||||
@@ -1141,3 +1190,95 @@ done:
|
||||
COGL_TIMER_STOP (_cogl_uprof_context, pipeline_flush_timer);
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_gl_set_uniform (CoglContext *ctx,
|
||||
GLint location,
|
||||
const CoglBoxedValue *value)
|
||||
{
|
||||
switch (value->type)
|
||||
{
|
||||
case COGL_BOXED_NONE:
|
||||
break;
|
||||
|
||||
case COGL_BOXED_INT:
|
||||
{
|
||||
const int *ptr;
|
||||
|
||||
if (value->count == 1)
|
||||
ptr = value->v.int_value;
|
||||
else
|
||||
ptr = value->v.int_array;
|
||||
|
||||
switch (value->size)
|
||||
{
|
||||
case 1:
|
||||
GE( ctx, glUniform1iv (location, value->count, ptr) );
|
||||
break;
|
||||
case 2:
|
||||
GE( ctx, glUniform2iv (location, value->count, ptr) );
|
||||
break;
|
||||
case 3:
|
||||
GE( ctx, glUniform3iv (location, value->count, ptr) );
|
||||
break;
|
||||
case 4:
|
||||
GE( ctx, glUniform4iv (location, value->count, ptr) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case COGL_BOXED_FLOAT:
|
||||
{
|
||||
const float *ptr;
|
||||
|
||||
if (value->count == 1)
|
||||
ptr = value->v.float_value;
|
||||
else
|
||||
ptr = value->v.float_array;
|
||||
|
||||
switch (value->size)
|
||||
{
|
||||
case 1:
|
||||
GE( ctx, glUniform1fv (location, value->count, ptr) );
|
||||
break;
|
||||
case 2:
|
||||
GE( ctx, glUniform2fv (location, value->count, ptr) );
|
||||
break;
|
||||
case 3:
|
||||
GE( ctx, glUniform3fv (location, value->count, ptr) );
|
||||
break;
|
||||
case 4:
|
||||
GE( ctx, glUniform4fv (location, value->count, ptr) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case COGL_BOXED_MATRIX:
|
||||
{
|
||||
const float *ptr;
|
||||
|
||||
if (value->count == 1)
|
||||
ptr = value->v.matrix;
|
||||
else
|
||||
ptr = value->v.float_array;
|
||||
|
||||
switch (value->size)
|
||||
{
|
||||
case 2:
|
||||
GE( ctx, glUniformMatrix2fv (location, value->count,
|
||||
FALSE, ptr) );
|
||||
break;
|
||||
case 3:
|
||||
GE( ctx, glUniformMatrix3fv (location, value->count,
|
||||
FALSE, ptr) );
|
||||
break;
|
||||
case 4:
|
||||
GE( ctx, glUniformMatrix4fv (location, value->count,
|
||||
FALSE, ptr) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@@ -633,6 +633,82 @@ _cogl_pipeline_progend_glsl_start (CoglPipeline *pipeline)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_cogl_shader_compile_real (CoglHandle handle,
|
||||
CoglPipeline *pipeline)
|
||||
{
|
||||
CoglShader *shader = handle;
|
||||
GLenum gl_type;
|
||||
GLint status;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
if (shader->gl_handle)
|
||||
{
|
||||
CoglPipeline *prev = shader->compilation_pipeline;
|
||||
|
||||
/* XXX: currently the only things that will affect the
|
||||
* boilerplate for user shaders, apart from driver features,
|
||||
* are the pipeline layer-indices and texture-unit-indices
|
||||
*/
|
||||
if (pipeline == prev ||
|
||||
_cogl_pipeline_layer_and_unit_numbers_equal (prev, pipeline))
|
||||
return;
|
||||
|
||||
GE (ctx, glDeleteShader (shader->gl_handle));
|
||||
shader->gl_handle = 0;
|
||||
|
||||
if (shader->compilation_pipeline)
|
||||
{
|
||||
cogl_object_unref (shader->compilation_pipeline);
|
||||
shader->compilation_pipeline = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
switch (shader->type)
|
||||
{
|
||||
case COGL_SHADER_TYPE_VERTEX:
|
||||
gl_type = GL_VERTEX_SHADER;
|
||||
break;
|
||||
case COGL_SHADER_TYPE_FRAGMENT:
|
||||
gl_type = GL_FRAGMENT_SHADER;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
shader->gl_handle = ctx->glCreateShader (gl_type);
|
||||
|
||||
_cogl_glsl_shader_set_source_with_boilerplate (ctx,
|
||||
shader->gl_handle,
|
||||
gl_type,
|
||||
pipeline,
|
||||
1,
|
||||
(const char **)
|
||||
&shader->source,
|
||||
NULL);
|
||||
GE (ctx, glCompileShader (shader->gl_handle));
|
||||
|
||||
shader->compilation_pipeline = cogl_object_ref (pipeline);
|
||||
|
||||
GE (ctx, glGetShaderiv (shader->gl_handle, GL_COMPILE_STATUS, &status));
|
||||
if (!status)
|
||||
{
|
||||
char buffer[512];
|
||||
int len = 0;
|
||||
|
||||
ctx->glGetShaderInfoLog (shader->gl_handle, 511, &len, buffer);
|
||||
buffer[len] = '\0';
|
||||
|
||||
g_warning ("Failed to compile GLSL program:\n"
|
||||
"src:\n%s\n"
|
||||
"error:\n%s\n",
|
||||
shader->source,
|
||||
buffer);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline,
|
||||
unsigned long pipelines_difference)
|
||||
@@ -877,6 +953,7 @@ _cogl_pipeline_progend_glsl_layer_pre_change_notify (
|
||||
CoglPipelineLayerState change)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
CoglTextureUnit *unit;
|
||||
|
||||
if ((change & (_cogl_pipeline_get_layer_state_for_fragment_codegen (ctx) |
|
||||
COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN)))
|
||||
@@ -901,6 +978,15 @@ _cogl_pipeline_progend_glsl_layer_pre_change_notify (
|
||||
program_state->unit_state[unit_index].dirty_texture_matrix = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the layer being changed is the same as the last layer we
|
||||
* flushed to the corresponding texture unit then we keep a track of
|
||||
* the changes so we can try to minimize redundant OpenGL calls if
|
||||
* the same layer is flushed again.
|
||||
*/
|
||||
unit = _cogl_get_texture_unit (_cogl_pipeline_layer_get_unit_index (layer));
|
||||
if (unit->layer == layer)
|
||||
unit->layer_changes_since_flush |= change;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -45,7 +45,7 @@
|
||||
#include "cogl-context-private.h"
|
||||
#include "cogl-object-private.h"
|
||||
#include "cogl-pipeline-state-private.h"
|
||||
#include "cogl-glsl-shader-private.h"
|
||||
#include "cogl-glsl-shader-boilerplate.h"
|
||||
#include "driver/gl/cogl-pipeline-vertend-glsl-private.h"
|
||||
#include "deprecated/cogl-program-private.h"
|
||||
|
||||
@@ -132,6 +132,150 @@ dirty_shader_state (CoglPipeline *pipeline)
|
||||
NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
add_layer_vertex_boilerplate_cb (CoglPipelineLayer *layer,
|
||||
void *user_data)
|
||||
{
|
||||
GString *layer_declarations = user_data;
|
||||
int unit_index = _cogl_pipeline_layer_get_unit_index (layer);
|
||||
g_string_append_printf (layer_declarations,
|
||||
"attribute vec4 cogl_tex_coord%d_in;\n"
|
||||
"#define cogl_texture_matrix%i cogl_texture_matrix[%i]\n"
|
||||
"#define cogl_tex_coord%i_out _cogl_tex_coord[%i]\n",
|
||||
layer->index,
|
||||
layer->index,
|
||||
unit_index,
|
||||
layer->index,
|
||||
unit_index);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
add_layer_fragment_boilerplate_cb (CoglPipelineLayer *layer,
|
||||
void *user_data)
|
||||
{
|
||||
GString *layer_declarations = user_data;
|
||||
g_string_append_printf (layer_declarations,
|
||||
"#define cogl_tex_coord%i_in _cogl_tex_coord[%i]\n",
|
||||
layer->index,
|
||||
_cogl_pipeline_layer_get_unit_index (layer));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
|
||||
GLuint shader_gl_handle,
|
||||
GLenum shader_gl_type,
|
||||
CoglPipeline *pipeline,
|
||||
GLsizei count_in,
|
||||
const char **strings_in,
|
||||
const GLint *lengths_in)
|
||||
{
|
||||
const char *vertex_boilerplate;
|
||||
const char *fragment_boilerplate;
|
||||
|
||||
const char **strings = g_alloca (sizeof (char *) * (count_in + 4));
|
||||
GLint *lengths = g_alloca (sizeof (GLint) * (count_in + 4));
|
||||
char *version_string;
|
||||
int count = 0;
|
||||
|
||||
int n_layers;
|
||||
|
||||
vertex_boilerplate = _COGL_VERTEX_SHADER_BOILERPLATE;
|
||||
fragment_boilerplate = _COGL_FRAGMENT_SHADER_BOILERPLATE;
|
||||
|
||||
version_string = g_strdup_printf ("#version %i\n\n",
|
||||
ctx->glsl_version_to_use);
|
||||
strings[count] = version_string;
|
||||
lengths[count++] = -1;
|
||||
|
||||
if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL))
|
||||
{
|
||||
static const char image_external_extension[] =
|
||||
"#extension GL_OES_EGL_image_external : require\n";
|
||||
strings[count] = image_external_extension;
|
||||
lengths[count++] = sizeof (image_external_extension) - 1;
|
||||
}
|
||||
|
||||
if (shader_gl_type == GL_VERTEX_SHADER)
|
||||
{
|
||||
strings[count] = vertex_boilerplate;
|
||||
lengths[count++] = strlen (vertex_boilerplate);
|
||||
}
|
||||
else if (shader_gl_type == GL_FRAGMENT_SHADER)
|
||||
{
|
||||
strings[count] = fragment_boilerplate;
|
||||
lengths[count++] = strlen (fragment_boilerplate);
|
||||
}
|
||||
|
||||
n_layers = cogl_pipeline_get_n_layers (pipeline);
|
||||
if (n_layers)
|
||||
{
|
||||
GString *layer_declarations = ctx->codegen_boilerplate_buffer;
|
||||
g_string_set_size (layer_declarations, 0);
|
||||
|
||||
g_string_append_printf (layer_declarations,
|
||||
"varying vec4 _cogl_tex_coord[%d];\n",
|
||||
n_layers);
|
||||
|
||||
if (shader_gl_type == GL_VERTEX_SHADER)
|
||||
{
|
||||
g_string_append_printf (layer_declarations,
|
||||
"uniform mat4 cogl_texture_matrix[%d];\n",
|
||||
n_layers);
|
||||
|
||||
_cogl_pipeline_foreach_layer_internal (pipeline,
|
||||
add_layer_vertex_boilerplate_cb,
|
||||
layer_declarations);
|
||||
}
|
||||
else if (shader_gl_type == GL_FRAGMENT_SHADER)
|
||||
{
|
||||
_cogl_pipeline_foreach_layer_internal (pipeline,
|
||||
add_layer_fragment_boilerplate_cb,
|
||||
layer_declarations);
|
||||
}
|
||||
|
||||
strings[count] = layer_declarations->str;
|
||||
lengths[count++] = -1; /* null terminated */
|
||||
}
|
||||
|
||||
memcpy (strings + count, strings_in, sizeof (char *) * count_in);
|
||||
if (lengths_in)
|
||||
memcpy (lengths + count, lengths_in, sizeof (GLint) * count_in);
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count_in; i++)
|
||||
lengths[count + i] = -1; /* null terminated */
|
||||
}
|
||||
count += count_in;
|
||||
|
||||
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SHOW_SOURCE)))
|
||||
{
|
||||
GString *buf = g_string_new (NULL);
|
||||
int i;
|
||||
|
||||
g_string_append_printf (buf,
|
||||
"%s shader:\n",
|
||||
shader_gl_type == GL_VERTEX_SHADER ?
|
||||
"vertex" : "fragment");
|
||||
for (i = 0; i < count; i++)
|
||||
if (lengths[i] != -1)
|
||||
g_string_append_len (buf, strings[i], lengths[i]);
|
||||
else
|
||||
g_string_append (buf, strings[i]);
|
||||
|
||||
g_message ("%s", buf->str);
|
||||
|
||||
g_string_free (buf, TRUE);
|
||||
}
|
||||
|
||||
GE( ctx, glShaderSource (shader_gl_handle, count,
|
||||
(const char **) strings, lengths) );
|
||||
|
||||
g_free (version_string);
|
||||
}
|
||||
GLuint
|
||||
_cogl_pipeline_vertend_glsl_get_shader (CoglPipeline *pipeline)
|
||||
{
|
||||
|
@@ -76,6 +76,18 @@ _cogl_gl_error_to_string (GLenum error_code);
|
||||
|
||||
#endif /* COGL_GL_DEBUG */
|
||||
|
||||
typedef struct _CoglGLContext {
|
||||
GArray *texture_units;
|
||||
int active_texture_unit;
|
||||
|
||||
/* This is used for generated fake unique sampler object numbers
|
||||
when the sampler object extension is not supported */
|
||||
GLuint next_fake_sampler_object_number;
|
||||
} CoglGLContext;
|
||||
|
||||
CoglGLContext *
|
||||
_cogl_driver_gl_context (CoglContext *context);
|
||||
|
||||
gboolean
|
||||
_cogl_driver_gl_context_init (CoglContext *context);
|
||||
|
||||
@@ -91,6 +103,23 @@ _cogl_gl_util_clear_gl_errors (CoglContext *ctx);
|
||||
gboolean
|
||||
_cogl_gl_util_catch_out_of_memory (CoglContext *ctx, GError **error);
|
||||
|
||||
gboolean
|
||||
_cogl_driver_gl_is_hardware_accelerated (CoglContext *context);
|
||||
|
||||
/*
|
||||
* _cogl_context_get_gl_extensions:
|
||||
* @context: A CoglContext
|
||||
*
|
||||
* Return value: a NULL-terminated array of strings representing the
|
||||
* supported extensions by the current driver. This array is owned
|
||||
* by the caller and should be freed with g_strfreev().
|
||||
*/
|
||||
char **
|
||||
_cogl_context_get_gl_extensions (CoglContext *context);
|
||||
|
||||
const char *
|
||||
_cogl_context_get_gl_version (CoglContext *context);
|
||||
|
||||
/* Parses a GL version number stored in a string. @version_string must
|
||||
* point to the beginning of the version number (ie, it can't point to
|
||||
* the "OpenGL ES" part on GLES). The version number can be followed
|
||||
@@ -102,4 +131,7 @@ _cogl_gl_util_parse_gl_version (const char *version_string,
|
||||
int *major_out,
|
||||
int *minor_out);
|
||||
|
||||
CoglGraphicsResetStatus
|
||||
_cogl_gl_get_graphics_reset_status (CoglContext *context);
|
||||
|
||||
#endif /* _COGL_UTIL_GL_PRIVATE_H_ */
|
||||
|
@@ -37,6 +37,24 @@
|
||||
#include "driver/gl/cogl-pipeline-opengl-private.h"
|
||||
#include "driver/gl/cogl-util-gl-private.h"
|
||||
|
||||
/* This is a relatively new extension */
|
||||
#ifndef GL_PURGED_CONTEXT_RESET_NV
|
||||
#define GL_PURGED_CONTEXT_RESET_NV 0x92BB
|
||||
#endif
|
||||
|
||||
/* These aren't defined in the GLES2 headers */
|
||||
#ifndef GL_GUILTY_CONTEXT_RESET_ARB
|
||||
#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253
|
||||
#endif
|
||||
|
||||
#ifndef GL_INNOCENT_CONTEXT_RESET_ARB
|
||||
#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254
|
||||
#endif
|
||||
|
||||
#ifndef GL_UNKNOWN_CONTEXT_RESET_ARB
|
||||
#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255
|
||||
#endif
|
||||
|
||||
#ifdef COGL_GL_DEBUG
|
||||
/* GL error to string conversion */
|
||||
static const struct {
|
||||
@@ -75,15 +93,31 @@ _cogl_gl_error_to_string (GLenum error_code)
|
||||
}
|
||||
#endif /* COGL_GL_DEBUG */
|
||||
|
||||
CoglGLContext *
|
||||
_cogl_driver_gl_context (CoglContext *context)
|
||||
{
|
||||
return context->driver_context;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_cogl_driver_gl_context_init (CoglContext *context)
|
||||
{
|
||||
context->texture_units =
|
||||
CoglGLContext *gl_context;
|
||||
|
||||
if (!context->driver_context)
|
||||
context->driver_context = g_new0 (CoglContext, 1);
|
||||
|
||||
gl_context = _cogl_driver_gl_context (context);
|
||||
if (!gl_context)
|
||||
return FALSE;
|
||||
|
||||
gl_context->next_fake_sampler_object_number = 1;
|
||||
gl_context->texture_units =
|
||||
g_array_new (FALSE, FALSE, sizeof (CoglTextureUnit));
|
||||
|
||||
/* See cogl-pipeline.c for more details about why we leave texture unit 1
|
||||
* active by default... */
|
||||
context->active_texture_unit = 1;
|
||||
gl_context->active_texture_unit = 1;
|
||||
GE (context, glActiveTexture (GL_TEXTURE1));
|
||||
|
||||
return TRUE;
|
||||
@@ -93,6 +127,7 @@ void
|
||||
_cogl_driver_gl_context_deinit (CoglContext *context)
|
||||
{
|
||||
_cogl_destroy_texture_units (context);
|
||||
g_free (context->driver_context);
|
||||
}
|
||||
|
||||
GLenum
|
||||
@@ -147,6 +182,94 @@ _cogl_gl_util_catch_out_of_memory (CoglContext *ctx, GError **error)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
char **
|
||||
_cogl_context_get_gl_extensions (CoglContext *context)
|
||||
{
|
||||
const char *env_disabled_extensions;
|
||||
char **ret;
|
||||
|
||||
/* In GL 3, querying GL_EXTENSIONS is deprecated so we have to build
|
||||
* the array using glGetStringi instead */
|
||||
#ifdef HAVE_COGL_GL
|
||||
if (context->driver == COGL_DRIVER_GL3)
|
||||
{
|
||||
int num_extensions, i;
|
||||
|
||||
context->glGetIntegerv (GL_NUM_EXTENSIONS, &num_extensions);
|
||||
|
||||
ret = g_malloc (sizeof (char *) * (num_extensions + 1));
|
||||
|
||||
for (i = 0; i < num_extensions; i++)
|
||||
{
|
||||
const char *ext =
|
||||
(const char *) context->glGetStringi (GL_EXTENSIONS, i);
|
||||
ret[i] = g_strdup (ext);
|
||||
}
|
||||
|
||||
ret[num_extensions] = NULL;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
const char *all_extensions =
|
||||
(const char *) context->glGetString (GL_EXTENSIONS);
|
||||
|
||||
ret = g_strsplit (all_extensions, " ", 0 /* max tokens */);
|
||||
}
|
||||
|
||||
if ((env_disabled_extensions = g_getenv ("COGL_DISABLE_GL_EXTENSIONS")))
|
||||
{
|
||||
char **split_env_disabled_extensions;
|
||||
char **src, **dst;
|
||||
|
||||
if (env_disabled_extensions)
|
||||
split_env_disabled_extensions =
|
||||
g_strsplit (env_disabled_extensions,
|
||||
",",
|
||||
0 /* no max tokens */);
|
||||
else
|
||||
split_env_disabled_extensions = NULL;
|
||||
|
||||
for (dst = ret, src = ret;
|
||||
*src;
|
||||
src++)
|
||||
{
|
||||
char **d;
|
||||
|
||||
if (split_env_disabled_extensions)
|
||||
for (d = split_env_disabled_extensions; *d; d++)
|
||||
if (!strcmp (*src, *d))
|
||||
goto disabled;
|
||||
|
||||
*(dst++) = *src;
|
||||
continue;
|
||||
|
||||
disabled:
|
||||
g_free (*src);
|
||||
continue;
|
||||
}
|
||||
|
||||
*dst = NULL;
|
||||
|
||||
if (split_env_disabled_extensions)
|
||||
g_strfreev (split_env_disabled_extensions);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char *
|
||||
_cogl_context_get_gl_version (CoglContext *context)
|
||||
{
|
||||
const char *version_override;
|
||||
|
||||
if ((version_override = g_getenv ("COGL_OVERRIDE_GL_VERSION")))
|
||||
return version_override;
|
||||
else
|
||||
return (const char *) context->glGetString (GL_VERSION);
|
||||
|
||||
}
|
||||
|
||||
gboolean
|
||||
_cogl_gl_util_parse_gl_version (const char *version_string,
|
||||
int *major_out,
|
||||
@@ -179,3 +302,53 @@ _cogl_gl_util_parse_gl_version (const char *version_string,
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* This should arguably use something like GLX_MESA_query_renderer, but
|
||||
* a) that's GLX-only, and you could add it to EGL too but
|
||||
* b) that'd make this a winsys query when really it's not a property of
|
||||
* the winsys but the renderer, and
|
||||
* c) only Mesa really supports it anyway, and
|
||||
* d) Mesa is the only software renderer of interest.
|
||||
*
|
||||
* So instead just check a list of known software renderer strings.
|
||||
*/
|
||||
gboolean
|
||||
_cogl_driver_gl_is_hardware_accelerated (CoglContext *ctx)
|
||||
{
|
||||
const char *renderer = (const char *) ctx->glGetString (GL_RENDERER);
|
||||
gboolean software;
|
||||
|
||||
software = strstr (renderer, "llvmpipe") != NULL ||
|
||||
strstr (renderer, "softpipe") != NULL ||
|
||||
strstr (renderer, "software rasterizer") != NULL ||
|
||||
strstr (renderer, "Software Rasterizer") != NULL ||
|
||||
strstr (renderer, "SWR");
|
||||
|
||||
return !software;
|
||||
}
|
||||
|
||||
CoglGraphicsResetStatus
|
||||
_cogl_gl_get_graphics_reset_status (CoglContext *context)
|
||||
{
|
||||
if (!context->glGetGraphicsResetStatus)
|
||||
return COGL_GRAPHICS_RESET_STATUS_NO_ERROR;
|
||||
|
||||
switch (context->glGetGraphicsResetStatus ())
|
||||
{
|
||||
case GL_GUILTY_CONTEXT_RESET_ARB:
|
||||
return COGL_GRAPHICS_RESET_STATUS_GUILTY_CONTEXT_RESET;
|
||||
|
||||
case GL_INNOCENT_CONTEXT_RESET_ARB:
|
||||
return COGL_GRAPHICS_RESET_STATUS_INNOCENT_CONTEXT_RESET;
|
||||
|
||||
case GL_UNKNOWN_CONTEXT_RESET_ARB:
|
||||
return COGL_GRAPHICS_RESET_STATUS_UNKNOWN_CONTEXT_RESET;
|
||||
|
||||
case GL_PURGED_CONTEXT_RESET_NV:
|
||||
return COGL_GRAPHICS_RESET_STATUS_PURGED_CONTEXT_RESET;
|
||||
|
||||
default:
|
||||
return COGL_GRAPHICS_RESET_STATUS_NO_ERROR;
|
||||
}
|
||||
}
|
||||
|
@@ -42,6 +42,7 @@
|
||||
#include "driver/gl/cogl-attribute-gl-private.h"
|
||||
#include "driver/gl/cogl-clip-stack-gl-private.h"
|
||||
#include "driver/gl/cogl-buffer-gl-private.h"
|
||||
#include "driver/gl/cogl-pipeline-opengl-private.h"
|
||||
|
||||
static gboolean
|
||||
_cogl_driver_gl_real_context_init (CoglContext *context)
|
||||
@@ -419,8 +420,6 @@ _cogl_driver_update_features (CoglContext *ctx,
|
||||
|
||||
_cogl_get_gl_version (ctx, &gl_major, &gl_minor);
|
||||
|
||||
_cogl_gpu_info_init (ctx, &ctx->gpu);
|
||||
|
||||
ctx->glsl_major = 1;
|
||||
ctx->glsl_minor = 2;
|
||||
ctx->glsl_version_to_use = 120;
|
||||
@@ -532,6 +531,8 @@ _cogl_driver_gl =
|
||||
{
|
||||
_cogl_driver_gl_real_context_init,
|
||||
_cogl_driver_gl_context_deinit,
|
||||
_cogl_driver_gl_is_hardware_accelerated,
|
||||
_cogl_gl_get_graphics_reset_status,
|
||||
_cogl_driver_pixel_format_from_gl_internal,
|
||||
_cogl_driver_pixel_format_to_gl,
|
||||
_cogl_driver_update_features,
|
||||
@@ -563,4 +564,7 @@ _cogl_driver_gl =
|
||||
_cogl_buffer_gl_map_range,
|
||||
_cogl_buffer_gl_unmap,
|
||||
_cogl_buffer_gl_set_data,
|
||||
_cogl_sampler_gl_init,
|
||||
_cogl_sampler_gl_free,
|
||||
_cogl_gl_set_uniform, /* XXX name is weird... */
|
||||
};
|
||||
|
@@ -42,6 +42,7 @@
|
||||
#include "driver/gl/cogl-attribute-gl-private.h"
|
||||
#include "driver/gl/cogl-clip-stack-gl-private.h"
|
||||
#include "driver/gl/cogl-buffer-gl-private.h"
|
||||
#include "driver/gl/cogl-pipeline-opengl-private.h"
|
||||
|
||||
#ifndef GL_UNSIGNED_INT_24_8
|
||||
#define GL_UNSIGNED_INT_24_8 0x84FA
|
||||
@@ -282,8 +283,6 @@ _cogl_driver_update_features (CoglContext *context,
|
||||
context->glsl_minor = 0;
|
||||
context->glsl_version_to_use = 100;
|
||||
|
||||
_cogl_gpu_info_init (context, &context->gpu);
|
||||
|
||||
if (!_cogl_get_gl_version (context, &gl_major, &gl_minor))
|
||||
{
|
||||
gl_major = 1;
|
||||
@@ -396,6 +395,8 @@ _cogl_driver_gles =
|
||||
{
|
||||
_cogl_driver_gl_context_init,
|
||||
_cogl_driver_gl_context_deinit,
|
||||
_cogl_driver_gl_is_hardware_accelerated,
|
||||
_cogl_gl_get_graphics_reset_status,
|
||||
_cogl_driver_pixel_format_from_gl_internal,
|
||||
_cogl_driver_pixel_format_to_gl,
|
||||
_cogl_driver_update_features,
|
||||
@@ -427,4 +428,7 @@ _cogl_driver_gles =
|
||||
_cogl_buffer_gl_map_range,
|
||||
_cogl_buffer_gl_unmap,
|
||||
_cogl_buffer_gl_set_data,
|
||||
_cogl_sampler_gl_init,
|
||||
_cogl_sampler_gl_free,
|
||||
_cogl_gl_set_uniform,
|
||||
};
|
||||
|
@@ -45,8 +45,6 @@ static gboolean
|
||||
_cogl_driver_update_features (CoglContext *ctx,
|
||||
GError **error)
|
||||
{
|
||||
/* _cogl_gpu_info_init (ctx, &ctx->gpu); */
|
||||
|
||||
memset (ctx->private_features, 0, sizeof (ctx->private_features));
|
||||
|
||||
return TRUE;
|
||||
@@ -63,11 +61,19 @@ _cogl_driver_nop_context_deinit (CoglContext *context)
|
||||
{
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_cogl_driver_nop_is_hardware_accelerated (CoglContext *context)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
const CoglDriverVtable
|
||||
_cogl_driver_nop =
|
||||
{
|
||||
_cogl_driver_nop_context_init,
|
||||
_cogl_driver_nop_context_deinit,
|
||||
_cogl_driver_nop_is_hardware_accelerated,
|
||||
NULL, /* get_graphics_reset_status */
|
||||
NULL, /* pixel_format_from_gl_internal */
|
||||
NULL, /* pixel_format_to_gl */
|
||||
_cogl_driver_update_features,
|
||||
|
@@ -208,8 +208,6 @@ cogl_sources = [
|
||||
'cogl-debug.h',
|
||||
'cogl-debug-options.h',
|
||||
'cogl-dma-buf-handle.c',
|
||||
'cogl-gpu-info.c',
|
||||
'cogl-gpu-info-private.h',
|
||||
'cogl-context-private.h',
|
||||
'cogl-context.c',
|
||||
'cogl-renderer-private.h',
|
||||
@@ -276,8 +274,6 @@ cogl_sources = [
|
||||
'cogl-pipeline-layer-state.c',
|
||||
'cogl-pipeline-state-private.h',
|
||||
'cogl-pipeline-debug.c',
|
||||
'cogl-glsl-shader.c',
|
||||
'cogl-glsl-shader-private.h',
|
||||
'cogl-glsl-shader-boilerplate.h',
|
||||
'cogl-pipeline-snippet-private.h',
|
||||
'cogl-pipeline-snippet.c',
|
||||
|
@@ -1662,8 +1662,6 @@ set_frame_info_output (CoglOnscreen *onscreen,
|
||||
{
|
||||
CoglFrameInfo *info = g_queue_peek_tail (&onscreen->pending_frame_infos);
|
||||
|
||||
info->output = output;
|
||||
|
||||
if (output)
|
||||
{
|
||||
float refresh_rate = cogl_output_get_refresh_rate (output);
|
||||
|
@@ -12,7 +12,7 @@ option('opengl_libname',
|
||||
|
||||
option('gles2_libname',
|
||||
type: 'string',
|
||||
value: 'libGLESv2.so',
|
||||
value: 'libGLESv2.so.2',
|
||||
description: 'GLESv2 library file name'
|
||||
)
|
||||
|
||||
|
@@ -156,10 +156,6 @@ xkb_layout_index_t meta_backend_get_keymap_layout_group (MetaBackend *backend);
|
||||
|
||||
gboolean meta_backend_is_lid_closed (MetaBackend *backend);
|
||||
|
||||
void meta_backend_freeze_updates (MetaBackend *backend);
|
||||
|
||||
void meta_backend_thaw_updates (MetaBackend *backend);
|
||||
|
||||
void meta_backend_update_last_device (MetaBackend *backend,
|
||||
ClutterInputDevice *device);
|
||||
|
||||
|
@@ -21,6 +21,8 @@
|
||||
#ifndef META_BACKEND_TYPE_H
|
||||
#define META_BACKEND_TYPE_H
|
||||
|
||||
typedef struct _MetaBackend MetaBackend;
|
||||
|
||||
typedef struct _MetaMonitorManager MetaMonitorManager;
|
||||
|
||||
typedef struct _MetaMonitorConfigManager MetaMonitorConfigManager;
|
||||
@@ -42,8 +44,9 @@ typedef struct _MetaGpu MetaGpu;
|
||||
typedef struct _MetaCrtc MetaCrtc;
|
||||
typedef struct _MetaOutput MetaOutput;
|
||||
typedef struct _MetaCrtcMode MetaCrtcMode;
|
||||
typedef struct _MetaCrtcInfo MetaCrtcInfo;
|
||||
typedef struct _MetaOutputInfo MetaOutputInfo;
|
||||
typedef struct _MetaCrtcAssignment MetaCrtcAssignment;
|
||||
typedef struct _MetaOutputAssignment MetaOutputAssignment;
|
||||
|
||||
typedef struct _MetaTileInfo MetaTileInfo;
|
||||
|
||||
typedef struct _MetaRenderer MetaRenderer;
|
||||
|
@@ -575,12 +575,6 @@ meta_backend_real_post_init (MetaBackend *backend)
|
||||
}
|
||||
}
|
||||
|
||||
static MetaCursorRenderer *
|
||||
meta_backend_real_create_cursor_renderer (MetaBackend *backend)
|
||||
{
|
||||
return meta_cursor_renderer_new ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_backend_real_grab_device (MetaBackend *backend,
|
||||
int device_id,
|
||||
@@ -762,7 +756,6 @@ meta_backend_class_init (MetaBackendClass *klass)
|
||||
object_class->constructed = meta_backend_constructed;
|
||||
|
||||
klass->post_init = meta_backend_real_post_init;
|
||||
klass->create_cursor_renderer = meta_backend_real_create_cursor_renderer;
|
||||
klass->grab_device = meta_backend_real_grab_device;
|
||||
klass->ungrab_device = meta_backend_real_ungrab_device;
|
||||
klass->select_stage_events = meta_backend_real_select_stage_events;
|
||||
@@ -1275,24 +1268,6 @@ meta_backend_get_stage (MetaBackend *backend)
|
||||
return priv->stage;
|
||||
}
|
||||
|
||||
void
|
||||
meta_backend_freeze_updates (MetaBackend *backend)
|
||||
{
|
||||
ClutterStage *stage;
|
||||
|
||||
stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
|
||||
clutter_stage_freeze_updates (stage);
|
||||
}
|
||||
|
||||
void
|
||||
meta_backend_thaw_updates (MetaBackend *backend)
|
||||
{
|
||||
ClutterStage *stage;
|
||||
|
||||
stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
|
||||
clutter_stage_thaw_updates (stage);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
update_last_device (MetaBackend *backend)
|
||||
{
|
||||
|
200
src/backends/meta-crtc-mode.c
Normal file
200
src/backends/meta-crtc-mode.c
Normal file
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2020 Red Hat
|
||||
*
|
||||
* 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/meta-crtc-mode.h"
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_ID,
|
||||
PROP_NAME,
|
||||
PROP_INFO,
|
||||
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[N_PROPS];
|
||||
|
||||
typedef struct _MetaCrtcModePrivate
|
||||
{
|
||||
uint64_t id;
|
||||
char *name;
|
||||
MetaCrtcModeInfo *info;
|
||||
} MetaCrtcModePrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaCrtcMode, meta_crtc_mode, G_TYPE_OBJECT)
|
||||
|
||||
G_DEFINE_BOXED_TYPE (MetaCrtcModeInfo, meta_crtc_mode_info,
|
||||
meta_crtc_mode_info_ref,
|
||||
meta_crtc_mode_info_unref)
|
||||
|
||||
MetaCrtcModeInfo *
|
||||
meta_crtc_mode_info_new (void)
|
||||
{
|
||||
MetaCrtcModeInfo *crtc_mode_info;
|
||||
|
||||
crtc_mode_info = g_new0 (MetaCrtcModeInfo, 1);
|
||||
g_ref_count_init (&crtc_mode_info->ref_count);
|
||||
|
||||
return crtc_mode_info;
|
||||
}
|
||||
|
||||
MetaCrtcModeInfo *
|
||||
meta_crtc_mode_info_ref (MetaCrtcModeInfo *crtc_mode_info)
|
||||
{
|
||||
g_ref_count_inc (&crtc_mode_info->ref_count);
|
||||
return crtc_mode_info;
|
||||
}
|
||||
|
||||
void
|
||||
meta_crtc_mode_info_unref (MetaCrtcModeInfo *crtc_mode_info)
|
||||
{
|
||||
if (g_ref_count_dec (&crtc_mode_info->ref_count))
|
||||
g_free (crtc_mode_info);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
meta_crtc_mode_get_id (MetaCrtcMode *crtc_mode)
|
||||
{
|
||||
MetaCrtcModePrivate *priv = meta_crtc_mode_get_instance_private (crtc_mode);
|
||||
|
||||
return priv->id;
|
||||
}
|
||||
|
||||
const char *
|
||||
meta_crtc_mode_get_name (MetaCrtcMode *crtc_mode)
|
||||
{
|
||||
MetaCrtcModePrivate *priv = meta_crtc_mode_get_instance_private (crtc_mode);
|
||||
|
||||
return priv->name;
|
||||
}
|
||||
|
||||
const MetaCrtcModeInfo *
|
||||
meta_crtc_mode_get_info (MetaCrtcMode *crtc_mode)
|
||||
{
|
||||
MetaCrtcModePrivate *priv = meta_crtc_mode_get_instance_private (crtc_mode);
|
||||
|
||||
return priv->info;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_crtc_mode_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaCrtcMode *crtc_mode = META_CRTC_MODE (object);
|
||||
MetaCrtcModePrivate *priv = meta_crtc_mode_get_instance_private (crtc_mode);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ID:
|
||||
priv->id = g_value_get_uint64 (value);
|
||||
break;
|
||||
case PROP_NAME:
|
||||
priv->name = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_INFO:
|
||||
priv->info = meta_crtc_mode_info_ref (g_value_get_boxed (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_crtc_mode_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaCrtcMode *crtc_mode = META_CRTC_MODE (object);
|
||||
MetaCrtcModePrivate *priv = meta_crtc_mode_get_instance_private (crtc_mode);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ID:
|
||||
g_value_set_uint64 (value, priv->id);
|
||||
break;
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, priv->name);
|
||||
break;
|
||||
case PROP_INFO:
|
||||
g_value_set_boxed (value, priv->info);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_crtc_mode_finalize (GObject *object)
|
||||
{
|
||||
MetaCrtcMode *crtc_mode = META_CRTC_MODE (object);
|
||||
MetaCrtcModePrivate *priv = meta_crtc_mode_get_instance_private (crtc_mode);
|
||||
|
||||
g_clear_pointer (&priv->name, g_free);
|
||||
g_clear_pointer (&priv->info, meta_crtc_mode_info_unref);
|
||||
|
||||
G_OBJECT_CLASS (meta_crtc_mode_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_crtc_mode_init (MetaCrtcMode *crtc_mode)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_crtc_mode_class_init (MetaCrtcModeClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->set_property = meta_crtc_mode_set_property;
|
||||
object_class->get_property = meta_crtc_mode_get_property;
|
||||
object_class->finalize = meta_crtc_mode_finalize;
|
||||
|
||||
obj_props[PROP_ID] =
|
||||
g_param_spec_uint64 ("id",
|
||||
"id",
|
||||
"CRTC mode id",
|
||||
0, UINT64_MAX, 0,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
obj_props[PROP_NAME] =
|
||||
g_param_spec_string ("name",
|
||||
"name",
|
||||
"Name of CRTC mode",
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
obj_props[PROP_INFO] =
|
||||
g_param_spec_boxed ("info",
|
||||
"info",
|
||||
"MetaOutputInfo",
|
||||
META_TYPE_CRTC_MODE_INFO,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_properties (object_class, N_PROPS, obj_props);
|
||||
}
|
92
src/backends/meta-crtc-mode.h
Normal file
92
src/backends/meta-crtc-mode.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2020 Red Hat
|
||||
*
|
||||
* 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_CRTC_MODE_H
|
||||
#define META_CRTC_MODE_H
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "core/util-private.h"
|
||||
|
||||
/* Same as KMS mode flags and X11 randr flags */
|
||||
typedef enum _MetaCrtcModeFlag
|
||||
{
|
||||
META_CRTC_MODE_FLAG_NONE = 0,
|
||||
META_CRTC_MODE_FLAG_PHSYNC = (1 << 0),
|
||||
META_CRTC_MODE_FLAG_NHSYNC = (1 << 1),
|
||||
META_CRTC_MODE_FLAG_PVSYNC = (1 << 2),
|
||||
META_CRTC_MODE_FLAG_NVSYNC = (1 << 3),
|
||||
META_CRTC_MODE_FLAG_INTERLACE = (1 << 4),
|
||||
META_CRTC_MODE_FLAG_DBLSCAN = (1 << 5),
|
||||
META_CRTC_MODE_FLAG_CSYNC = (1 << 6),
|
||||
META_CRTC_MODE_FLAG_PCSYNC = (1 << 7),
|
||||
META_CRTC_MODE_FLAG_NCSYNC = (1 << 8),
|
||||
META_CRTC_MODE_FLAG_HSKEW = (1 << 9),
|
||||
META_CRTC_MODE_FLAG_BCAST = (1 << 10),
|
||||
META_CRTC_MODE_FLAG_PIXMUX = (1 << 11),
|
||||
META_CRTC_MODE_FLAG_DBLCLK = (1 << 12),
|
||||
META_CRTC_MODE_FLAG_CLKDIV2 = (1 << 13),
|
||||
|
||||
META_CRTC_MODE_FLAG_MASK = 0x3fff
|
||||
} MetaCrtcModeFlag;
|
||||
|
||||
typedef struct _MetaCrtcModeInfo
|
||||
{
|
||||
grefcount ref_count;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
float refresh_rate;
|
||||
MetaCrtcModeFlag flags;
|
||||
} MetaCrtcModeInfo;
|
||||
|
||||
#define META_TYPE_CRTC_MODE (meta_crtc_mode_get_type ())
|
||||
META_EXPORT_TEST
|
||||
G_DECLARE_DERIVABLE_TYPE (MetaCrtcMode, meta_crtc_mode,
|
||||
META, CRTC_MODE,
|
||||
GObject)
|
||||
|
||||
struct _MetaCrtcModeClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
#define META_TYPE_CRTC_MODE_INFO (meta_crtc_mode_info_get_type ())
|
||||
GType meta_crtc_mode_info_get_type (void);
|
||||
|
||||
META_EXPORT_TEST
|
||||
MetaCrtcModeInfo * meta_crtc_mode_info_new (void);
|
||||
|
||||
META_EXPORT_TEST
|
||||
MetaCrtcModeInfo * meta_crtc_mode_info_ref (MetaCrtcModeInfo *crtc_mode_info);
|
||||
|
||||
META_EXPORT_TEST
|
||||
void meta_crtc_mode_info_unref (MetaCrtcModeInfo *crtc_mode_info);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaCrtcModeInfo, meta_crtc_mode_info_unref)
|
||||
|
||||
uint64_t meta_crtc_mode_get_id (MetaCrtcMode *crtc_mode);
|
||||
|
||||
const char * meta_crtc_mode_get_name (MetaCrtcMode *crtc_mode);
|
||||
|
||||
META_EXPORT_TEST
|
||||
const MetaCrtcModeInfo * meta_crtc_mode_get_info (MetaCrtcMode *crtc_mode);
|
||||
|
||||
#endif /* META_CRTC_MODE_H */
|
@@ -21,14 +21,56 @@
|
||||
|
||||
#include "backends/meta-crtc.h"
|
||||
|
||||
G_DEFINE_TYPE (MetaCrtc, meta_crtc, G_TYPE_OBJECT)
|
||||
#include "backends/meta-gpu.h"
|
||||
|
||||
G_DEFINE_TYPE (MetaCrtcMode, meta_crtc_mode, G_TYPE_OBJECT)
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_ID,
|
||||
PROP_GPU,
|
||||
PROP_ALL_TRANSFORMS,
|
||||
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[N_PROPS];
|
||||
|
||||
typedef struct _MetaCrtcPrivate
|
||||
{
|
||||
uint64_t id;
|
||||
|
||||
MetaGpu *gpu;
|
||||
|
||||
MetaMonitorTransform all_transforms;
|
||||
|
||||
MetaCrtcConfig *config;
|
||||
} MetaCrtcPrivate;
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaCrtc, meta_crtc, G_TYPE_OBJECT)
|
||||
|
||||
uint64_t
|
||||
meta_crtc_get_id (MetaCrtc *crtc)
|
||||
{
|
||||
MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
|
||||
|
||||
return priv->id;
|
||||
}
|
||||
|
||||
MetaGpu *
|
||||
meta_crtc_get_gpu (MetaCrtc *crtc)
|
||||
{
|
||||
return crtc->gpu;
|
||||
MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
|
||||
|
||||
return priv->gpu;
|
||||
}
|
||||
|
||||
MetaMonitorTransform
|
||||
meta_crtc_get_all_transforms (MetaCrtc *crtc)
|
||||
{
|
||||
MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
|
||||
|
||||
return priv->all_transforms;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -37,6 +79,7 @@ meta_crtc_set_config (MetaCrtc *crtc,
|
||||
MetaCrtcMode *mode,
|
||||
MetaMonitorTransform transform)
|
||||
{
|
||||
MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
|
||||
MetaCrtcConfig *config;
|
||||
|
||||
meta_crtc_unset_config (crtc);
|
||||
@@ -46,24 +89,82 @@ meta_crtc_set_config (MetaCrtc *crtc,
|
||||
config->mode = mode;
|
||||
config->transform = transform;
|
||||
|
||||
crtc->config = config;
|
||||
priv->config = config;
|
||||
}
|
||||
|
||||
void
|
||||
meta_crtc_unset_config (MetaCrtc *crtc)
|
||||
{
|
||||
g_clear_pointer (&crtc->config, g_free);
|
||||
MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
|
||||
|
||||
g_clear_pointer (&priv->config, g_free);
|
||||
}
|
||||
|
||||
const MetaCrtcConfig *
|
||||
meta_crtc_get_config (MetaCrtc *crtc)
|
||||
{
|
||||
MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
|
||||
|
||||
return priv->config;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_crtc_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaCrtc *crtc = META_CRTC (object);
|
||||
MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ID:
|
||||
priv->id = g_value_get_uint64 (value);
|
||||
break;
|
||||
case PROP_GPU:
|
||||
priv->gpu = g_value_get_object (value);
|
||||
break;
|
||||
case PROP_ALL_TRANSFORMS:
|
||||
priv->all_transforms = g_value_get_uint (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_crtc_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaCrtc *crtc = META_CRTC (object);
|
||||
MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ID:
|
||||
g_value_set_uint64 (value, priv->id);
|
||||
break;
|
||||
case PROP_GPU:
|
||||
g_value_set_object (value, priv->gpu);
|
||||
break;
|
||||
case PROP_ALL_TRANSFORMS:
|
||||
g_value_set_uint (value, priv->all_transforms);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_crtc_finalize (GObject *object)
|
||||
{
|
||||
MetaCrtc *crtc = META_CRTC (object);
|
||||
MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
|
||||
|
||||
if (crtc->driver_notify)
|
||||
crtc->driver_notify (crtc);
|
||||
|
||||
g_clear_pointer (&crtc->config, g_free);
|
||||
g_clear_pointer (&priv->config, g_free);
|
||||
|
||||
G_OBJECT_CLASS (meta_crtc_parent_class)->finalize (object);
|
||||
}
|
||||
@@ -71,6 +172,9 @@ meta_crtc_finalize (GObject *object)
|
||||
static void
|
||||
meta_crtc_init (MetaCrtc *crtc)
|
||||
{
|
||||
MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
|
||||
|
||||
priv->all_transforms = META_MONITOR_ALL_TRANSFORMS;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -78,31 +182,35 @@ meta_crtc_class_init (MetaCrtcClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->set_property = meta_crtc_set_property;
|
||||
object_class->get_property = meta_crtc_get_property;
|
||||
object_class->finalize = meta_crtc_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_crtc_mode_finalize (GObject *object)
|
||||
{
|
||||
MetaCrtcMode *crtc_mode = META_CRTC_MODE (object);
|
||||
|
||||
if (crtc_mode->driver_notify)
|
||||
crtc_mode->driver_notify (crtc_mode);
|
||||
|
||||
g_clear_pointer (&crtc_mode->name, g_free);
|
||||
|
||||
G_OBJECT_CLASS (meta_crtc_mode_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_crtc_mode_init (MetaCrtcMode *crtc_mode)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_crtc_mode_class_init (MetaCrtcModeClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = meta_crtc_mode_finalize;
|
||||
|
||||
obj_props[PROP_ID] =
|
||||
g_param_spec_uint64 ("id",
|
||||
"id",
|
||||
"CRTC id",
|
||||
0, UINT64_MAX, 0,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
obj_props[PROP_GPU] =
|
||||
g_param_spec_object ("gpu",
|
||||
"gpu",
|
||||
"MetaGpu",
|
||||
META_TYPE_GPU,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
obj_props[PROP_ALL_TRANSFORMS] =
|
||||
g_param_spec_uint ("all-transforms",
|
||||
"all-transforms",
|
||||
"All transforms",
|
||||
0,
|
||||
META_MONITOR_ALL_TRANSFORMS,
|
||||
META_MONITOR_ALL_TRANSFORMS,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_properties (object_class, N_PROPS, obj_props);
|
||||
}
|
||||
|
@@ -23,32 +23,11 @@
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "backends/meta-backend-types.h"
|
||||
#include "backends/meta-crtc-mode.h"
|
||||
#include "backends/meta-monitor-transform.h"
|
||||
#include "core/util-private.h"
|
||||
#include "meta/boxes.h"
|
||||
|
||||
/* Same as KMS mode flags and X11 randr flags */
|
||||
typedef enum _MetaCrtcModeFlag
|
||||
{
|
||||
META_CRTC_MODE_FLAG_NONE = 0,
|
||||
META_CRTC_MODE_FLAG_PHSYNC = (1 << 0),
|
||||
META_CRTC_MODE_FLAG_NHSYNC = (1 << 1),
|
||||
META_CRTC_MODE_FLAG_PVSYNC = (1 << 2),
|
||||
META_CRTC_MODE_FLAG_NVSYNC = (1 << 3),
|
||||
META_CRTC_MODE_FLAG_INTERLACE = (1 << 4),
|
||||
META_CRTC_MODE_FLAG_DBLSCAN = (1 << 5),
|
||||
META_CRTC_MODE_FLAG_CSYNC = (1 << 6),
|
||||
META_CRTC_MODE_FLAG_PCSYNC = (1 << 7),
|
||||
META_CRTC_MODE_FLAG_NCSYNC = (1 << 8),
|
||||
META_CRTC_MODE_FLAG_HSKEW = (1 << 9),
|
||||
META_CRTC_MODE_FLAG_BCAST = (1 << 10),
|
||||
META_CRTC_MODE_FLAG_PIXMUX = (1 << 11),
|
||||
META_CRTC_MODE_FLAG_DBLCLK = (1 << 12),
|
||||
META_CRTC_MODE_FLAG_CLKDIV2 = (1 << 13),
|
||||
|
||||
META_CRTC_MODE_FLAG_MASK = 0x3fff
|
||||
} MetaCrtcModeFlag;
|
||||
|
||||
typedef struct _MetaCrtcConfig
|
||||
{
|
||||
graphene_rect_t layout;
|
||||
@@ -56,52 +35,23 @@ typedef struct _MetaCrtcConfig
|
||||
MetaCrtcMode *mode;
|
||||
} MetaCrtcConfig;
|
||||
|
||||
struct _MetaCrtc
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
MetaGpu *gpu;
|
||||
|
||||
glong crtc_id;
|
||||
unsigned int all_transforms;
|
||||
|
||||
MetaCrtcConfig *config;
|
||||
|
||||
/* Used when changing configuration */
|
||||
gboolean is_dirty;
|
||||
|
||||
/* Used by cursor renderer backend */
|
||||
void *cursor_renderer_private;
|
||||
|
||||
gpointer driver_private;
|
||||
GDestroyNotify driver_notify;
|
||||
};
|
||||
|
||||
struct _MetaCrtcMode
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
/* The low-level ID of this mode, used to apply back configuration */
|
||||
glong mode_id;
|
||||
char *name;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
float refresh_rate;
|
||||
MetaCrtcModeFlag flags;
|
||||
|
||||
gpointer driver_private;
|
||||
GDestroyNotify driver_notify;
|
||||
};
|
||||
|
||||
#define META_TYPE_CRTC (meta_crtc_get_type ())
|
||||
META_EXPORT_TEST G_DECLARE_FINAL_TYPE (MetaCrtc, meta_crtc, META, CRTC, GObject)
|
||||
META_EXPORT_TEST
|
||||
G_DECLARE_DERIVABLE_TYPE (MetaCrtc, meta_crtc, META, CRTC, GObject)
|
||||
|
||||
#define META_TYPE_CRTC_MODE (meta_crtc_mode_get_type ())
|
||||
META_EXPORT_TEST G_DECLARE_FINAL_TYPE (MetaCrtcMode, meta_crtc_mode, META, CRTC_MODE, GObject)
|
||||
struct _MetaCrtcClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
META_EXPORT_TEST
|
||||
uint64_t meta_crtc_get_id (MetaCrtc *crtc);
|
||||
|
||||
META_EXPORT_TEST
|
||||
MetaGpu * meta_crtc_get_gpu (MetaCrtc *crtc);
|
||||
|
||||
MetaMonitorTransform meta_crtc_get_all_transforms (MetaCrtc *crtc);
|
||||
|
||||
META_EXPORT_TEST
|
||||
void meta_crtc_set_config (MetaCrtc *crtc,
|
||||
graphene_rect_t *layout,
|
||||
@@ -111,4 +61,7 @@ void meta_crtc_set_config (MetaCrtc *crtc,
|
||||
META_EXPORT_TEST
|
||||
void meta_crtc_unset_config (MetaCrtc *crtc);
|
||||
|
||||
META_EXPORT_TEST
|
||||
const MetaCrtcConfig * meta_crtc_get_config (MetaCrtc *crtc);
|
||||
|
||||
#endif /* META_CRTC_H */
|
||||
|
@@ -38,8 +38,21 @@
|
||||
G_DEFINE_INTERFACE (MetaHwCursorInhibitor, meta_hw_cursor_inhibitor,
|
||||
G_TYPE_OBJECT)
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_BACKEND,
|
||||
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[N_PROPS];
|
||||
|
||||
struct _MetaCursorRendererPrivate
|
||||
{
|
||||
MetaBackend *backend;
|
||||
|
||||
float current_x;
|
||||
float current_y;
|
||||
|
||||
@@ -89,8 +102,7 @@ align_cursor_position (MetaCursorRenderer *renderer,
|
||||
{
|
||||
MetaCursorRendererPrivate *priv =
|
||||
meta_cursor_renderer_get_instance_private (renderer);
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
ClutterActor *stage = meta_backend_get_stage (backend);
|
||||
ClutterActor *stage = meta_backend_get_stage (priv->backend);
|
||||
ClutterStageView *view;
|
||||
cairo_rectangle_int_t view_layout;
|
||||
float view_scale;
|
||||
@@ -115,8 +127,7 @@ queue_redraw (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
ClutterActor *stage = meta_backend_get_stage (backend);
|
||||
ClutterActor *stage = meta_backend_get_stage (priv->backend);
|
||||
CoglTexture *texture;
|
||||
graphene_rect_t rect = GRAPHENE_RECT_INIT_ZERO;
|
||||
|
||||
@@ -165,13 +176,54 @@ meta_cursor_renderer_real_update_cursor (MetaCursorRenderer *renderer,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_renderer_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaCursorRenderer *renderer = META_CURSOR_RENDERER (object);
|
||||
MetaCursorRendererPrivate *priv =
|
||||
meta_cursor_renderer_get_instance_private (renderer);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_BACKEND:
|
||||
g_value_set_object (value, priv->backend);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_renderer_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaCursorRenderer *renderer = META_CURSOR_RENDERER (object);
|
||||
MetaCursorRendererPrivate *priv =
|
||||
meta_cursor_renderer_get_instance_private (renderer);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_BACKEND:
|
||||
priv->backend = g_value_get_object (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_renderer_finalize (GObject *object)
|
||||
{
|
||||
MetaCursorRenderer *renderer = META_CURSOR_RENDERER (object);
|
||||
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
ClutterActor *stage = meta_backend_get_stage (backend);
|
||||
ClutterActor *stage = meta_backend_get_stage (priv->backend);
|
||||
|
||||
if (priv->stage_overlay)
|
||||
meta_stage_remove_cursor_overlay (META_STAGE (stage), priv->stage_overlay);
|
||||
@@ -186,9 +238,21 @@ meta_cursor_renderer_class_init (MetaCursorRendererClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->get_property = meta_cursor_renderer_get_property;
|
||||
object_class->set_property = meta_cursor_renderer_set_property;
|
||||
object_class->finalize = meta_cursor_renderer_finalize;
|
||||
klass->update_cursor = meta_cursor_renderer_real_update_cursor;
|
||||
|
||||
obj_props[PROP_BACKEND] =
|
||||
g_param_spec_object ("backend",
|
||||
"backend",
|
||||
"MetaBackend",
|
||||
META_TYPE_BACKEND,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_properties (object_class, N_PROPS, obj_props);
|
||||
|
||||
signals[CURSOR_PAINTED] = g_signal_new ("cursor-painted",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
@@ -273,9 +337,11 @@ meta_cursor_renderer_update_cursor (MetaCursorRenderer *renderer,
|
||||
}
|
||||
|
||||
MetaCursorRenderer *
|
||||
meta_cursor_renderer_new (void)
|
||||
meta_cursor_renderer_new (MetaBackend *backend)
|
||||
{
|
||||
return g_object_new (META_TYPE_CURSOR_RENDERER, NULL);
|
||||
return g_object_new (META_TYPE_CURSOR_RENDERER,
|
||||
"backend", backend,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -54,7 +54,7 @@ struct _MetaCursorRendererClass
|
||||
MetaCursorSprite *cursor_sprite);
|
||||
};
|
||||
|
||||
MetaCursorRenderer * meta_cursor_renderer_new (void);
|
||||
MetaCursorRenderer * meta_cursor_renderer_new (MetaBackend *backend);
|
||||
|
||||
void meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite);
|
||||
|
@@ -57,8 +57,9 @@ meta_gpu_has_hotplug_mode_update (MetaGpu *gpu)
|
||||
for (l = priv->outputs; l; l = l->next)
|
||||
{
|
||||
MetaOutput *output = l->data;
|
||||
const MetaOutputInfo *output_info = meta_output_get_info (output);
|
||||
|
||||
if (output->hotplug_mode_update)
|
||||
if (output_info->hotplug_mode_update)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
56
src/backends/meta-keymap-utils.c
Normal file
56
src/backends/meta-keymap-utils.c
Normal file
@@ -0,0 +1,56 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* Utilities for use with libxkbcommon
|
||||
*
|
||||
* Copyright 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "backends/meta-keymap-utils.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <limits.h>
|
||||
|
||||
struct xkb_context *
|
||||
meta_create_xkb_context (void)
|
||||
{
|
||||
struct xkb_context *ctx;
|
||||
char xdg[PATH_MAX] = {0};
|
||||
const char *env;
|
||||
|
||||
/*
|
||||
* We can only append search paths in libxkbcommon, so we start with an
|
||||
* emtpy set, then add the XDG dir, then add the default search paths.
|
||||
*/
|
||||
ctx = xkb_context_new (XKB_CONTEXT_NO_DEFAULT_INCLUDES);
|
||||
|
||||
env = g_getenv ("XDG_CONFIG_HOME");
|
||||
if (env)
|
||||
{
|
||||
g_snprintf (xdg, sizeof xdg, "%s/xkb", env);
|
||||
}
|
||||
else if ((env = g_getenv ("HOME")))
|
||||
{
|
||||
g_snprintf (xdg, sizeof xdg, "%s/.config/xkb", env);
|
||||
}
|
||||
|
||||
if (env)
|
||||
xkb_context_include_path_append (ctx, xdg);
|
||||
xkb_context_include_path_append_default (ctx);
|
||||
|
||||
return ctx;
|
||||
}
|
28
src/backends/meta-keymap-utils.h
Normal file
28
src/backends/meta-keymap-utils.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* Utilities for use with libxkbcommon
|
||||
*
|
||||
* Copyright 2020 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef META_KEYMAP_UTILS_H
|
||||
#define META_KEYMAP_UTILS_H
|
||||
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
struct xkb_context * meta_create_xkb_context (void);
|
||||
|
||||
#endif /* META_KEYMAP_UTILS_H */
|
@@ -99,7 +99,7 @@ meta_logical_monitor_new (MetaMonitorManager *monitor_manager,
|
||||
main_output = meta_monitor_get_main_output (first_monitor);
|
||||
|
||||
logical_monitor->number = monitor_number;
|
||||
logical_monitor->winsys_id = main_output->winsys_id;
|
||||
logical_monitor->winsys_id = meta_output_get_id (main_output);
|
||||
logical_monitor->scale = logical_monitor_config->scale;
|
||||
logical_monitor->transform = logical_monitor_config->transform;
|
||||
logical_monitor->in_fullscreen = -1;
|
||||
@@ -119,10 +119,14 @@ static MetaMonitorTransform
|
||||
derive_monitor_transform (MetaMonitor *monitor)
|
||||
{
|
||||
MetaOutput *main_output;
|
||||
MetaCrtc *crtc;
|
||||
const MetaCrtcConfig *crtc_config;
|
||||
MetaMonitorTransform transform;
|
||||
|
||||
main_output = meta_monitor_get_main_output (monitor);
|
||||
transform = meta_output_get_assigned_crtc (main_output)->config->transform;
|
||||
crtc = meta_output_get_assigned_crtc (main_output);
|
||||
crtc_config = meta_crtc_get_config (crtc);
|
||||
transform = crtc_config->transform;
|
||||
|
||||
return meta_monitor_crtc_to_logical_transform (monitor, transform);
|
||||
}
|
||||
@@ -144,7 +148,7 @@ meta_logical_monitor_new_derived (MetaMonitorManager *monitor_manager,
|
||||
|
||||
main_output = meta_monitor_get_main_output (monitor);
|
||||
logical_monitor->number = monitor_number;
|
||||
logical_monitor->winsys_id = main_output->winsys_id;
|
||||
logical_monitor->winsys_id = meta_output_get_id (main_output);
|
||||
logical_monitor->scale = scale;
|
||||
logical_monitor->transform = transform;
|
||||
logical_monitor->in_fullscreen = -1;
|
||||
@@ -178,7 +182,8 @@ meta_logical_monitor_add_monitor (MetaLogicalMonitor *logical_monitor,
|
||||
{
|
||||
MetaOutput *output = l_output->data;
|
||||
|
||||
is_presentation = is_presentation && output->is_presentation;
|
||||
is_presentation = (is_presentation &&
|
||||
meta_output_is_presentation (output));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -52,10 +52,10 @@ G_DEFINE_TYPE (MetaMonitorsConfig, meta_monitors_config,
|
||||
G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
meta_crtc_info_free (MetaCrtcInfo *info);
|
||||
meta_crtc_assignment_free (MetaCrtcAssignment *assignment);
|
||||
|
||||
static void
|
||||
meta_output_info_free (MetaOutputInfo *info);
|
||||
meta_output_assignment_free (MetaOutputAssignment *assignment);
|
||||
|
||||
MetaMonitorConfigManager *
|
||||
meta_monitor_config_manager_new (MetaMonitorManager *monitor_manager)
|
||||
@@ -84,8 +84,10 @@ is_crtc_reserved (MetaCrtc *crtc,
|
||||
|
||||
for (i = 0; i < reserved_crtcs->len; i++)
|
||||
{
|
||||
glong id = g_array_index (reserved_crtcs, glong, i);
|
||||
if (id == crtc->crtc_id)
|
||||
uint64_t id;
|
||||
|
||||
id = g_array_index (reserved_crtcs, uint64_t, i);
|
||||
if (id == meta_crtc_get_id (crtc))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -94,15 +96,16 @@ is_crtc_reserved (MetaCrtc *crtc,
|
||||
|
||||
static gboolean
|
||||
is_crtc_assigned (MetaCrtc *crtc,
|
||||
GPtrArray *crtc_infos)
|
||||
GPtrArray *crtc_assignments)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < crtc_infos->len; i++)
|
||||
for (i = 0; i < crtc_assignments->len; i++)
|
||||
{
|
||||
MetaCrtcInfo *assigned_crtc_info = g_ptr_array_index (crtc_infos, i);
|
||||
MetaCrtcAssignment *assigned_crtc_assignment =
|
||||
g_ptr_array_index (crtc_assignments, i);
|
||||
|
||||
if (assigned_crtc_info->crtc == crtc)
|
||||
if (assigned_crtc_assignment->crtc == crtc)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -111,22 +114,25 @@ is_crtc_assigned (MetaCrtc *crtc,
|
||||
|
||||
static MetaCrtc *
|
||||
find_unassigned_crtc (MetaOutput *output,
|
||||
GPtrArray *crtc_infos,
|
||||
GPtrArray *crtc_assignments,
|
||||
GArray *reserved_crtcs)
|
||||
{
|
||||
MetaCrtc *crtc;
|
||||
const MetaOutputInfo *output_info;
|
||||
unsigned int i;
|
||||
|
||||
crtc = meta_output_get_assigned_crtc (output);
|
||||
if (crtc && !is_crtc_assigned (crtc, crtc_infos))
|
||||
if (crtc && !is_crtc_assigned (crtc, crtc_assignments))
|
||||
return crtc;
|
||||
|
||||
/* then try to assign a CRTC that wasn't used */
|
||||
for (i = 0; i < output->n_possible_crtcs; i++)
|
||||
{
|
||||
crtc = output->possible_crtcs[i];
|
||||
output_info = meta_output_get_info (output);
|
||||
|
||||
if (is_crtc_assigned (crtc, crtc_infos))
|
||||
/* then try to assign a CRTC that wasn't used */
|
||||
for (i = 0; i < output_info->n_possible_crtcs; i++)
|
||||
{
|
||||
crtc = output_info->possible_crtcs[i];
|
||||
|
||||
if (is_crtc_assigned (crtc, crtc_assignments))
|
||||
continue;
|
||||
|
||||
if (is_crtc_reserved (crtc, reserved_crtcs))
|
||||
@@ -136,11 +142,11 @@ find_unassigned_crtc (MetaOutput *output,
|
||||
}
|
||||
|
||||
/* finally just give a CRTC that we haven't assigned */
|
||||
for (i = 0; i < output->n_possible_crtcs; i++)
|
||||
for (i = 0; i < output_info->n_possible_crtcs; i++)
|
||||
{
|
||||
crtc = output->possible_crtcs[i];
|
||||
crtc = output_info->possible_crtcs[i];
|
||||
|
||||
if (is_crtc_assigned (crtc, crtc_infos))
|
||||
if (is_crtc_assigned (crtc, crtc_assignments))
|
||||
continue;
|
||||
|
||||
return crtc;
|
||||
@@ -155,8 +161,8 @@ typedef struct
|
||||
MetaMonitorsConfig *config;
|
||||
MetaLogicalMonitorConfig *logical_monitor_config;
|
||||
MetaMonitorConfig *monitor_config;
|
||||
GPtrArray *crtc_infos;
|
||||
GPtrArray *output_infos;
|
||||
GPtrArray *crtc_assignments;
|
||||
GPtrArray *output_assignments;
|
||||
GArray *reserved_crtcs;
|
||||
} MonitorAssignmentData;
|
||||
|
||||
@@ -178,16 +184,19 @@ assign_monitor_crtc (MetaMonitor *monitor,
|
||||
float scale = 0.0;
|
||||
float width, height;
|
||||
MetaCrtcMode *crtc_mode;
|
||||
const MetaCrtcModeInfo *crtc_mode_info;
|
||||
graphene_rect_t crtc_layout;
|
||||
MetaCrtcInfo *crtc_info;
|
||||
MetaOutputInfo *output_info;
|
||||
MetaCrtcAssignment *crtc_assignment;
|
||||
MetaOutputAssignment *output_assignment;
|
||||
MetaMonitorConfig *first_monitor_config;
|
||||
gboolean assign_output_as_primary;
|
||||
gboolean assign_output_as_presentation;
|
||||
|
||||
output = monitor_crtc_mode->output;
|
||||
|
||||
crtc = find_unassigned_crtc (output, data->crtc_infos, data->reserved_crtcs);
|
||||
crtc = find_unassigned_crtc (output,
|
||||
data->crtc_assignments,
|
||||
data->reserved_crtcs);
|
||||
|
||||
if (!crtc)
|
||||
{
|
||||
@@ -225,16 +234,17 @@ assign_monitor_crtc (MetaMonitor *monitor,
|
||||
}
|
||||
|
||||
crtc_mode = monitor_crtc_mode->crtc_mode;
|
||||
crtc_mode_info = meta_crtc_mode_get_info (monitor_crtc_mode->crtc_mode);
|
||||
|
||||
if (meta_monitor_transform_is_rotated (crtc_transform))
|
||||
{
|
||||
width = crtc_mode->height / scale;
|
||||
height = crtc_mode->width / scale;
|
||||
width = crtc_mode_info->height / scale;
|
||||
height = crtc_mode_info->width / scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
width = crtc_mode->width / scale;
|
||||
height = crtc_mode->height / scale;
|
||||
width = crtc_mode_info->width / scale;
|
||||
height = crtc_mode_info->height / scale;
|
||||
}
|
||||
|
||||
crtc_layout = GRAPHENE_RECT_INIT (x_offset + (crtc_x / scale),
|
||||
@@ -242,15 +252,15 @@ assign_monitor_crtc (MetaMonitor *monitor,
|
||||
width,
|
||||
height);
|
||||
|
||||
crtc_info = g_slice_new0 (MetaCrtcInfo);
|
||||
*crtc_info = (MetaCrtcInfo) {
|
||||
crtc_assignment = g_slice_new0 (MetaCrtcAssignment);
|
||||
*crtc_assignment = (MetaCrtcAssignment) {
|
||||
.crtc = crtc,
|
||||
.mode = crtc_mode,
|
||||
.layout = crtc_layout,
|
||||
.transform = crtc_hw_transform,
|
||||
.outputs = g_ptr_array_new ()
|
||||
};
|
||||
g_ptr_array_add (crtc_info->outputs, output);
|
||||
g_ptr_array_add (crtc_assignment->outputs, output);
|
||||
|
||||
/*
|
||||
* Only one output can be marked as primary (due to Xrandr limitation),
|
||||
@@ -270,16 +280,16 @@ assign_monitor_crtc (MetaMonitor *monitor,
|
||||
else
|
||||
assign_output_as_presentation = FALSE;
|
||||
|
||||
output_info = g_slice_new0 (MetaOutputInfo);
|
||||
*output_info = (MetaOutputInfo) {
|
||||
output_assignment = g_slice_new0 (MetaOutputAssignment);
|
||||
*output_assignment = (MetaOutputAssignment) {
|
||||
.output = output,
|
||||
.is_primary = assign_output_as_primary,
|
||||
.is_presentation = assign_output_as_presentation,
|
||||
.is_underscanning = data->monitor_config->enable_underscanning
|
||||
};
|
||||
|
||||
g_ptr_array_add (data->crtc_infos, crtc_info);
|
||||
g_ptr_array_add (data->output_infos, output_info);
|
||||
g_ptr_array_add (data->crtc_assignments, crtc_assignment);
|
||||
g_ptr_array_add (data->output_assignments, output_assignment);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -289,8 +299,8 @@ assign_monitor_crtcs (MetaMonitorManager *manager,
|
||||
MetaMonitorsConfig *config,
|
||||
MetaLogicalMonitorConfig *logical_monitor_config,
|
||||
MetaMonitorConfig *monitor_config,
|
||||
GPtrArray *crtc_infos,
|
||||
GPtrArray *output_infos,
|
||||
GPtrArray *crtc_assignments,
|
||||
GPtrArray *output_assignments,
|
||||
GArray *reserved_crtcs,
|
||||
GError **error)
|
||||
{
|
||||
@@ -325,8 +335,8 @@ assign_monitor_crtcs (MetaMonitorManager *manager,
|
||||
.config = config,
|
||||
.logical_monitor_config = logical_monitor_config,
|
||||
.monitor_config = monitor_config,
|
||||
.crtc_infos = crtc_infos,
|
||||
.output_infos = output_infos,
|
||||
.crtc_assignments = crtc_assignments,
|
||||
.output_assignments = output_assignments,
|
||||
.reserved_crtcs = reserved_crtcs
|
||||
};
|
||||
if (!meta_monitor_mode_foreach_crtc (monitor, monitor_mode,
|
||||
@@ -342,8 +352,8 @@ static gboolean
|
||||
assign_logical_monitor_crtcs (MetaMonitorManager *manager,
|
||||
MetaMonitorsConfig *config,
|
||||
MetaLogicalMonitorConfig *logical_monitor_config,
|
||||
GPtrArray *crtc_infos,
|
||||
GPtrArray *output_infos,
|
||||
GPtrArray *crtc_assignments,
|
||||
GPtrArray *output_assignments,
|
||||
GArray *reserved_crtcs,
|
||||
GError **error)
|
||||
{
|
||||
@@ -357,7 +367,7 @@ assign_logical_monitor_crtcs (MetaMonitorManager *manager,
|
||||
config,
|
||||
logical_monitor_config,
|
||||
monitor_config,
|
||||
crtc_infos, output_infos,
|
||||
crtc_assignments, output_assignments,
|
||||
reserved_crtcs, error))
|
||||
return FALSE;
|
||||
}
|
||||
@@ -368,20 +378,20 @@ assign_logical_monitor_crtcs (MetaMonitorManager *manager,
|
||||
gboolean
|
||||
meta_monitor_config_manager_assign (MetaMonitorManager *manager,
|
||||
MetaMonitorsConfig *config,
|
||||
GPtrArray **out_crtc_infos,
|
||||
GPtrArray **out_output_infos,
|
||||
GPtrArray **out_crtc_assignments,
|
||||
GPtrArray **out_output_assignments,
|
||||
GError **error)
|
||||
{
|
||||
GPtrArray *crtc_infos;
|
||||
GPtrArray *output_infos;
|
||||
GPtrArray *crtc_assignments;
|
||||
GPtrArray *output_assignments;
|
||||
GArray *reserved_crtcs;
|
||||
GList *l;
|
||||
|
||||
crtc_infos =
|
||||
g_ptr_array_new_with_free_func ((GDestroyNotify) meta_crtc_info_free);
|
||||
output_infos =
|
||||
g_ptr_array_new_with_free_func ((GDestroyNotify) meta_output_info_free);
|
||||
reserved_crtcs = g_array_new (FALSE, FALSE, sizeof (glong));
|
||||
crtc_assignments =
|
||||
g_ptr_array_new_with_free_func ((GDestroyNotify) meta_crtc_assignment_free);
|
||||
output_assignments =
|
||||
g_ptr_array_new_with_free_func ((GDestroyNotify) meta_output_assignment_free);
|
||||
reserved_crtcs = g_array_new (FALSE, FALSE, sizeof (uint64_t));
|
||||
|
||||
for (l = config->logical_monitor_configs; l; l = l->next)
|
||||
{
|
||||
@@ -404,7 +414,11 @@ meta_monitor_config_manager_assign (MetaMonitorManager *manager,
|
||||
|
||||
crtc = meta_output_get_assigned_crtc (output);
|
||||
if (crtc)
|
||||
g_array_append_val (reserved_crtcs, crtc->crtc_id);
|
||||
{
|
||||
uint64_t crtc_id = meta_crtc_get_id (crtc);
|
||||
|
||||
g_array_append_val (reserved_crtcs, crtc_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -415,11 +429,11 @@ meta_monitor_config_manager_assign (MetaMonitorManager *manager,
|
||||
|
||||
if (!assign_logical_monitor_crtcs (manager,
|
||||
config, logical_monitor_config,
|
||||
crtc_infos, output_infos,
|
||||
crtc_assignments, output_assignments,
|
||||
reserved_crtcs, error))
|
||||
{
|
||||
g_ptr_array_free (crtc_infos, TRUE);
|
||||
g_ptr_array_free (output_infos, TRUE);
|
||||
g_ptr_array_free (crtc_assignments, TRUE);
|
||||
g_ptr_array_free (output_assignments, TRUE);
|
||||
g_array_free (reserved_crtcs, TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
@@ -427,8 +441,8 @@ meta_monitor_config_manager_assign (MetaMonitorManager *manager,
|
||||
|
||||
g_array_free (reserved_crtcs, TRUE);
|
||||
|
||||
*out_crtc_infos = crtc_infos;
|
||||
*out_output_infos = output_infos;
|
||||
*out_crtc_assignments = crtc_assignments;
|
||||
*out_output_assignments = output_assignments;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1557,16 +1571,16 @@ meta_monitors_config_class_init (MetaMonitorsConfigClass *klass)
|
||||
}
|
||||
|
||||
static void
|
||||
meta_crtc_info_free (MetaCrtcInfo *info)
|
||||
meta_crtc_assignment_free (MetaCrtcAssignment *assignment)
|
||||
{
|
||||
g_ptr_array_free (info->outputs, TRUE);
|
||||
g_slice_free (MetaCrtcInfo, info);
|
||||
g_ptr_array_free (assignment->outputs, TRUE);
|
||||
g_slice_free (MetaCrtcAssignment, assignment);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_output_info_free (MetaOutputInfo *info)
|
||||
meta_output_assignment_free (MetaOutputAssignment *assignment)
|
||||
{
|
||||
g_slice_free (MetaOutputInfo, info);
|
||||
g_slice_free (MetaOutputAssignment, assignment);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
@@ -87,8 +87,8 @@ MetaMonitorConfigStore * meta_monitor_config_manager_get_store (MetaMonitorConfi
|
||||
META_EXPORT_TEST
|
||||
gboolean meta_monitor_config_manager_assign (MetaMonitorManager *manager,
|
||||
MetaMonitorsConfig *config,
|
||||
GPtrArray **crtc_infos,
|
||||
GPtrArray **output_infos,
|
||||
GPtrArray **crtc_assignments,
|
||||
GPtrArray **output_assignments,
|
||||
GError **error);
|
||||
|
||||
META_EXPORT_TEST
|
||||
|
@@ -36,8 +36,6 @@
|
||||
#include "backends/meta-output.h"
|
||||
#include "meta/util.h"
|
||||
|
||||
#define ALL_TRANSFORMS ((1 << (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1)
|
||||
|
||||
#define MAX_MONITORS 5
|
||||
#define MAX_OUTPUTS (MAX_MONITORS * 2)
|
||||
#define MAX_CRTCS (MAX_MONITORS * 2)
|
||||
@@ -55,11 +53,20 @@ struct _MetaMonitorManagerDummyClass
|
||||
MetaMonitorManagerClass parent_class;
|
||||
};
|
||||
|
||||
typedef struct _MetaOutputDummy
|
||||
struct _MetaOutputDummy
|
||||
{
|
||||
float scale;
|
||||
} MetaOutputDummy;
|
||||
MetaOutput parent;
|
||||
|
||||
float scale;
|
||||
};
|
||||
|
||||
struct _MetaCrtcDummy
|
||||
{
|
||||
MetaCrtc parent;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaOutputDummy, meta_output_dummy, META_TYPE_OUTPUT)
|
||||
G_DEFINE_TYPE (MetaCrtcDummy, meta_crtc_dummy, META_TYPE_CRTC)
|
||||
G_DEFINE_TYPE (MetaMonitorManagerDummy, meta_monitor_manager_dummy, META_TYPE_MONITOR_MANAGER);
|
||||
|
||||
struct _MetaGpuDummy
|
||||
@@ -69,9 +76,6 @@ struct _MetaGpuDummy
|
||||
|
||||
G_DEFINE_TYPE (MetaGpuDummy, meta_gpu_dummy, META_TYPE_GPU)
|
||||
|
||||
static void
|
||||
meta_output_dummy_notify_destroy (MetaOutput *output);
|
||||
|
||||
typedef struct _CrtcModeSpec
|
||||
{
|
||||
int width;
|
||||
@@ -84,16 +88,17 @@ static MetaCrtcMode *
|
||||
create_mode (CrtcModeSpec *spec,
|
||||
long mode_id)
|
||||
{
|
||||
MetaCrtcMode *mode;
|
||||
g_autoptr (MetaCrtcModeInfo) crtc_mode_info = NULL;
|
||||
|
||||
mode = g_object_new (META_TYPE_CRTC_MODE, NULL);
|
||||
crtc_mode_info = meta_crtc_mode_info_new ();
|
||||
crtc_mode_info->width = spec->width;
|
||||
crtc_mode_info->height = spec->height;
|
||||
crtc_mode_info->refresh_rate = spec->refresh_rate;
|
||||
|
||||
mode->mode_id = mode_id;
|
||||
mode->width = spec->width;
|
||||
mode->height = spec->height;
|
||||
mode->refresh_rate = spec->refresh_rate;
|
||||
|
||||
return mode;
|
||||
return g_object_new (META_TYPE_CRTC_MODE,
|
||||
"id", mode_id,
|
||||
"info", crtc_mode_info,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static MetaGpu *
|
||||
@@ -142,6 +147,7 @@ append_monitor (MetaMonitorManager *manager,
|
||||
MetaOutput *output;
|
||||
unsigned int i;
|
||||
unsigned int number;
|
||||
g_autoptr (MetaOutputInfo) output_info = NULL;
|
||||
const char *mode_specs_str;
|
||||
GList *l;
|
||||
|
||||
@@ -198,50 +204,45 @@ append_monitor (MetaMonitorManager *manager,
|
||||
}
|
||||
*modes = g_list_concat (*modes, new_modes);
|
||||
|
||||
crtc = g_object_new (META_TYPE_CRTC, NULL);
|
||||
crtc->crtc_id = g_list_length (*crtcs) + 1;
|
||||
crtc->all_transforms = ALL_TRANSFORMS;
|
||||
crtc = g_object_new (META_TYPE_CRTC_DUMMY,
|
||||
"id", g_list_length (*crtcs) + 1,
|
||||
"gpu", gpu,
|
||||
NULL);
|
||||
*crtcs = g_list_append (*crtcs, crtc);
|
||||
|
||||
output = g_object_new (META_TYPE_OUTPUT, NULL);
|
||||
|
||||
output_dummy = g_new0 (MetaOutputDummy, 1);
|
||||
*output_dummy = (MetaOutputDummy) {
|
||||
.scale = scale
|
||||
};
|
||||
|
||||
number = g_list_length (*outputs) + 1;
|
||||
|
||||
output->gpu = gpu;
|
||||
output->winsys_id = number;
|
||||
output->name = g_strdup_printf ("LVDS%d", number);
|
||||
output->vendor = g_strdup ("MetaProducts Inc.");
|
||||
output->product = g_strdup ("MetaMonitor");
|
||||
output->serial = g_strdup_printf ("0xC0FFEE-%d", number);
|
||||
output->suggested_x = -1;
|
||||
output->suggested_y = -1;
|
||||
output->width_mm = 222;
|
||||
output->height_mm = 125;
|
||||
output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
|
||||
output->preferred_mode = g_list_last (*modes)->data;
|
||||
output->n_possible_clones = 0;
|
||||
output->backlight = -1;
|
||||
output->connector_type = META_CONNECTOR_TYPE_LVDS;
|
||||
output->driver_private = output_dummy;
|
||||
output->driver_notify =
|
||||
(GDestroyNotify) meta_output_dummy_notify_destroy;
|
||||
output_info = meta_output_info_new ();
|
||||
output_info->name = g_strdup_printf ("LVDS%d", number);
|
||||
output_info->vendor = g_strdup ("MetaProducts Inc.");
|
||||
output_info->product = g_strdup ("MetaMonitor");
|
||||
output_info->serial = g_strdup_printf ("0xC0FFEE-%d", number);
|
||||
output_info->width_mm = 222;
|
||||
output_info->height_mm = 125;
|
||||
output_info->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
|
||||
output_info->preferred_mode = g_list_last (*modes)->data;
|
||||
output_info->n_possible_clones = 0;
|
||||
output_info->connector_type = META_CONNECTOR_TYPE_LVDS;
|
||||
|
||||
output->modes = g_new0 (MetaCrtcMode *, n_mode_specs);
|
||||
output_info->modes = g_new0 (MetaCrtcMode *, n_mode_specs);
|
||||
for (l = new_modes, i = 0; l; l = l->next, i++)
|
||||
{
|
||||
MetaCrtcMode *mode = l->data;
|
||||
|
||||
output->modes[i] = mode;
|
||||
output_info->modes[i] = mode;
|
||||
}
|
||||
output->n_modes = n_mode_specs;
|
||||
output->possible_crtcs = g_new0 (MetaCrtc *, 1);
|
||||
output->possible_crtcs[0] = g_list_last (*crtcs)->data;
|
||||
output->n_possible_crtcs = 1;
|
||||
output_info->n_modes = n_mode_specs;
|
||||
output_info->possible_crtcs = g_new0 (MetaCrtc *, 1);
|
||||
output_info->possible_crtcs[0] = g_list_last (*crtcs)->data;
|
||||
output_info->n_possible_crtcs = 1;
|
||||
|
||||
output = g_object_new (META_TYPE_OUTPUT_DUMMY,
|
||||
"id", number,
|
||||
"gpu", gpu,
|
||||
"info", output_info,
|
||||
NULL);
|
||||
output_dummy = META_OUTPUT_DUMMY (output);
|
||||
output_dummy->scale = scale;
|
||||
|
||||
*outputs = g_list_append (*outputs, output);
|
||||
}
|
||||
@@ -289,10 +290,10 @@ append_tiled_monitor (MetaMonitorManager *manager,
|
||||
{
|
||||
MetaCrtc *crtc;
|
||||
|
||||
crtc = g_object_new (META_TYPE_CRTC, NULL);
|
||||
crtc->gpu = gpu;
|
||||
crtc->crtc_id = g_list_length (*crtcs) + i + 1;
|
||||
crtc->all_transforms = ALL_TRANSFORMS;
|
||||
crtc = g_object_new (META_TYPE_CRTC_DUMMY,
|
||||
"id", g_list_length (*crtcs) + i + 1,
|
||||
"gpu", gpu,
|
||||
NULL);
|
||||
new_crtcs = g_list_append (new_crtcs, crtc);
|
||||
}
|
||||
*crtcs = g_list_concat (*crtcs, new_crtcs);
|
||||
@@ -302,78 +303,72 @@ append_tiled_monitor (MetaMonitorManager *manager,
|
||||
{
|
||||
MetaOutputDummy *output_dummy;
|
||||
MetaCrtcMode *preferred_mode;
|
||||
const MetaCrtcModeInfo *preferred_mode_info;
|
||||
unsigned int j;
|
||||
unsigned int number;
|
||||
g_autoptr (MetaOutputInfo) output_info = NULL;
|
||||
GList *l;
|
||||
|
||||
output_dummy = g_new0 (MetaOutputDummy, 1);
|
||||
*output_dummy = (MetaOutputDummy) {
|
||||
.scale = scale
|
||||
};
|
||||
|
||||
/* Arbitrary ID unique for this output */
|
||||
number = g_list_length (*outputs) + 1;
|
||||
|
||||
preferred_mode = g_list_last (*modes)->data;
|
||||
preferred_mode_info = meta_crtc_mode_get_info (preferred_mode);
|
||||
|
||||
output = g_object_new (META_TYPE_OUTPUT, NULL);
|
||||
output_info = meta_output_info_new ();
|
||||
|
||||
output->gpu = gpu;
|
||||
output->winsys_id = number;
|
||||
output->name = g_strdup_printf ("LVDS%d", number);
|
||||
output->vendor = g_strdup ("MetaProducts Inc.");
|
||||
output->product = g_strdup ("MetaMonitor");
|
||||
output->serial = g_strdup_printf ("0xC0FFEE-%d", number);
|
||||
output->suggested_x = -1;
|
||||
output->suggested_y = -1;
|
||||
output->width_mm = 222;
|
||||
output->height_mm = 125;
|
||||
output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
|
||||
output->preferred_mode = preferred_mode;
|
||||
output->n_possible_clones = 0;
|
||||
output->backlight = -1;
|
||||
output->connector_type = META_CONNECTOR_TYPE_LVDS;
|
||||
output->tile_info = (MetaTileInfo) {
|
||||
output_info->name = g_strdup_printf ("LVDS%d", number);
|
||||
output_info->vendor = g_strdup ("MetaProducts Inc.");
|
||||
output_info->product = g_strdup ("MetaMonitor");
|
||||
output_info->serial = g_strdup_printf ("0xC0FFEE-%d", number);
|
||||
output_info->suggested_x = -1;
|
||||
output_info->suggested_y = -1;
|
||||
output_info->width_mm = 222;
|
||||
output_info->height_mm = 125;
|
||||
output_info->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
|
||||
output_info->preferred_mode = preferred_mode;
|
||||
output_info->n_possible_clones = 0;
|
||||
output_info->connector_type = META_CONNECTOR_TYPE_LVDS;
|
||||
output_info->tile_info = (MetaTileInfo) {
|
||||
.group_id = tile_group_id,
|
||||
.max_h_tiles = n_tiles,
|
||||
.max_v_tiles = 1,
|
||||
.loc_h_tile = i,
|
||||
.loc_v_tile = 0,
|
||||
.tile_w = preferred_mode->width,
|
||||
.tile_h = preferred_mode->height
|
||||
.tile_w = preferred_mode_info->width,
|
||||
.tile_h = preferred_mode_info->height
|
||||
},
|
||||
output->driver_private = output_dummy;
|
||||
output->driver_notify =
|
||||
(GDestroyNotify) meta_output_dummy_notify_destroy;
|
||||
|
||||
output->modes = g_new0 (MetaCrtcMode *, G_N_ELEMENTS (mode_specs));
|
||||
output_info->modes = g_new0 (MetaCrtcMode *, G_N_ELEMENTS (mode_specs));
|
||||
for (l = new_modes, j = 0; l; l = l->next, j++)
|
||||
{
|
||||
MetaCrtcMode *mode = l->data;
|
||||
|
||||
output->modes[j] = mode;
|
||||
output_info->modes[j] = mode;
|
||||
}
|
||||
output->n_modes = G_N_ELEMENTS (mode_specs);
|
||||
output_info->n_modes = G_N_ELEMENTS (mode_specs);
|
||||
|
||||
output->possible_crtcs = g_new0 (MetaCrtc *, n_tiles);
|
||||
output_info->possible_crtcs = g_new0 (MetaCrtc *, n_tiles);
|
||||
for (l = new_crtcs, j = 0; l; l = l->next, j++)
|
||||
{
|
||||
MetaCrtc *crtc = l->data;
|
||||
|
||||
output->possible_crtcs[j] = crtc;
|
||||
output_info->possible_crtcs[j] = crtc;
|
||||
}
|
||||
output->n_possible_crtcs = n_tiles;
|
||||
output_info->n_possible_crtcs = n_tiles;
|
||||
|
||||
output = g_object_new (META_TYPE_OUTPUT_DUMMY,
|
||||
"id", number,
|
||||
"gpu", gpu,
|
||||
"info", output_info,
|
||||
NULL);
|
||||
output_dummy = META_OUTPUT_DUMMY (output);
|
||||
output_dummy->scale = scale;
|
||||
|
||||
*outputs = g_list_append (*outputs, output);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_output_dummy_notify_destroy (MetaOutput *output)
|
||||
{
|
||||
g_clear_pointer (&output->driver_private, g_free);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
|
||||
{
|
||||
@@ -495,82 +490,63 @@ meta_monitor_manager_dummy_ensure_initial_config (MetaMonitorManager *manager)
|
||||
}
|
||||
|
||||
static void
|
||||
apply_crtc_assignments (MetaMonitorManager *manager,
|
||||
MetaCrtcInfo **crtcs,
|
||||
unsigned int n_crtcs,
|
||||
MetaOutputInfo **outputs,
|
||||
unsigned int n_outputs)
|
||||
apply_crtc_assignments (MetaMonitorManager *manager,
|
||||
MetaCrtcAssignment **crtcs,
|
||||
unsigned int n_crtcs,
|
||||
MetaOutputAssignment **outputs,
|
||||
unsigned int n_outputs)
|
||||
{
|
||||
GList *l;
|
||||
g_autoptr (GList) to_configure_outputs = NULL;
|
||||
g_autoptr (GList) to_configure_crtcs = NULL;
|
||||
unsigned i;
|
||||
|
||||
to_configure_outputs = g_list_copy (meta_gpu_get_outputs (get_gpu (manager)));
|
||||
to_configure_crtcs = g_list_copy (meta_gpu_get_crtcs (get_gpu (manager)));
|
||||
|
||||
for (i = 0; i < n_crtcs; i++)
|
||||
{
|
||||
MetaCrtcInfo *crtc_info = crtcs[i];
|
||||
MetaCrtc *crtc = crtc_info->crtc;
|
||||
crtc->is_dirty = TRUE;
|
||||
MetaCrtcAssignment *crtc_assignment = crtcs[i];
|
||||
MetaCrtc *crtc = crtc_assignment->crtc;
|
||||
|
||||
if (crtc_info->mode == NULL)
|
||||
to_configure_crtcs = g_list_remove (to_configure_crtcs, crtc);
|
||||
|
||||
if (crtc_assignment->mode == NULL)
|
||||
{
|
||||
meta_crtc_unset_config (crtc);
|
||||
}
|
||||
else
|
||||
{
|
||||
MetaOutput *output;
|
||||
unsigned int j;
|
||||
|
||||
meta_crtc_set_config (crtc,
|
||||
&crtc_info->layout,
|
||||
crtc_info->mode,
|
||||
crtc_info->transform);
|
||||
&crtc_assignment->layout,
|
||||
crtc_assignment->mode,
|
||||
crtc_assignment->transform);
|
||||
|
||||
for (j = 0; j < crtc_info->outputs->len; j++)
|
||||
for (j = 0; j < crtc_assignment->outputs->len; j++)
|
||||
{
|
||||
output = ((MetaOutput**)crtc_info->outputs->pdata)[j];
|
||||
MetaOutput *output;
|
||||
MetaOutputAssignment *output_assignment;
|
||||
|
||||
output->is_dirty = TRUE;
|
||||
meta_output_assign_crtc (output, crtc);
|
||||
output = ((MetaOutput**) crtc_assignment->outputs->pdata)[j];
|
||||
|
||||
to_configure_outputs = g_list_remove (to_configure_outputs,
|
||||
output);
|
||||
|
||||
output_assignment = meta_find_output_assignment (outputs,
|
||||
n_outputs,
|
||||
output);
|
||||
meta_output_assign_crtc (output, crtc, output_assignment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
{
|
||||
MetaOutputInfo *output_info = outputs[i];
|
||||
MetaOutput *output = output_info->output;
|
||||
|
||||
output->is_primary = output_info->is_primary;
|
||||
output->is_presentation = output_info->is_presentation;
|
||||
}
|
||||
|
||||
/* Disable CRTCs not mentioned in the list */
|
||||
for (l = meta_gpu_get_crtcs (get_gpu (manager)); l; l = l->next)
|
||||
{
|
||||
MetaCrtc *crtc = l->data;
|
||||
|
||||
if (crtc->is_dirty)
|
||||
{
|
||||
crtc->is_dirty = FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
meta_crtc_unset_config (crtc);
|
||||
}
|
||||
|
||||
/* Disable outputs not mentioned in the list */
|
||||
for (l = meta_gpu_get_outputs (get_gpu (manager)); l; l = l->next)
|
||||
{
|
||||
MetaOutput *output = l->data;
|
||||
|
||||
if (output->is_dirty)
|
||||
{
|
||||
output->is_dirty = FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
meta_output_unassign_crtc (output);
|
||||
output->is_primary = FALSE;
|
||||
}
|
||||
g_list_foreach (to_configure_crtcs,
|
||||
(GFunc) meta_crtc_unset_config,
|
||||
NULL);
|
||||
g_list_foreach (to_configure_outputs,
|
||||
(GFunc) meta_output_unassign_crtc,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -608,8 +584,8 @@ meta_monitor_manager_dummy_apply_monitors_config (MetaMonitorManager *manag
|
||||
MetaMonitorsConfigMethod method,
|
||||
GError **error)
|
||||
{
|
||||
GPtrArray *crtc_infos;
|
||||
GPtrArray *output_infos;
|
||||
GPtrArray *crtc_assignments;
|
||||
GPtrArray *output_assignments;
|
||||
|
||||
if (!config)
|
||||
{
|
||||
@@ -621,25 +597,26 @@ meta_monitor_manager_dummy_apply_monitors_config (MetaMonitorManager *manag
|
||||
}
|
||||
|
||||
if (!meta_monitor_config_manager_assign (manager, config,
|
||||
&crtc_infos, &output_infos,
|
||||
&crtc_assignments,
|
||||
&output_assignments,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
if (method == META_MONITORS_CONFIG_METHOD_VERIFY)
|
||||
{
|
||||
g_ptr_array_free (crtc_infos, TRUE);
|
||||
g_ptr_array_free (output_infos, TRUE);
|
||||
g_ptr_array_free (crtc_assignments, TRUE);
|
||||
g_ptr_array_free (output_assignments, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
apply_crtc_assignments (manager,
|
||||
(MetaCrtcInfo **) crtc_infos->pdata,
|
||||
crtc_infos->len,
|
||||
(MetaOutputInfo **) output_infos->pdata,
|
||||
output_infos->len);
|
||||
(MetaCrtcAssignment **) crtc_assignments->pdata,
|
||||
crtc_assignments->len,
|
||||
(MetaOutputAssignment **) output_assignments->pdata,
|
||||
output_assignments->len);
|
||||
|
||||
g_ptr_array_free (crtc_infos, TRUE);
|
||||
g_ptr_array_free (output_infos, TRUE);
|
||||
g_ptr_array_free (crtc_assignments, TRUE);
|
||||
g_ptr_array_free (output_assignments, TRUE);
|
||||
|
||||
update_screen_size (manager, config);
|
||||
meta_monitor_manager_rebuild (manager, config);
|
||||
@@ -666,7 +643,7 @@ meta_monitor_manager_dummy_calculate_monitor_mode_scale (MetaMonitorManager *man
|
||||
MetaOutputDummy *output_dummy;
|
||||
|
||||
output = meta_monitor_get_main_output (monitor);
|
||||
output_dummy = output->driver_private;
|
||||
output_dummy = META_OUTPUT_DUMMY (output);
|
||||
|
||||
return output_dummy->scale;
|
||||
}
|
||||
@@ -813,3 +790,24 @@ meta_gpu_dummy_class_init (MetaGpuDummyClass *klass)
|
||||
|
||||
gpu_class->read_current = meta_gpu_dummy_read_current;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_output_dummy_init (MetaOutputDummy *output_dummy)
|
||||
{
|
||||
output_dummy->scale = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_output_dummy_class_init (MetaOutputDummyClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_crtc_dummy_init (MetaCrtcDummy *crtc_dummy)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_crtc_dummy_class_init (MetaCrtcDummyClass *klass)
|
||||
{
|
||||
}
|
||||
|
@@ -23,8 +23,20 @@
|
||||
#ifndef META_MONITOR_MANAGER_DUMMY_H
|
||||
#define META_MONITOR_MANAGER_DUMMY_H
|
||||
|
||||
#include "backends/meta-crtc.h"
|
||||
#include "backends/meta-gpu.h"
|
||||
#include "backends/meta-monitor-manager-private.h"
|
||||
#include "backends/meta-output.h"
|
||||
|
||||
#define META_TYPE_OUTPUT_DUMMY (meta_output_dummy_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaOutputDummy, meta_output_dummy,
|
||||
META, OUTPUT_DUMMY,
|
||||
MetaOutput)
|
||||
|
||||
#define META_TYPE_CRTC_DUMMY (meta_crtc_dummy_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaCrtcDummy, meta_crtc_dummy,
|
||||
META, CRTC_DUMMY,
|
||||
MetaCrtc)
|
||||
|
||||
#define META_TYPE_MONITOR_MANAGER_DUMMY (meta_monitor_manager_dummy_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaMonitorManagerDummy, meta_monitor_manager_dummy,
|
||||
|
@@ -63,12 +63,12 @@ typedef enum _MetaLogicalMonitorLayoutMode
|
||||
} MetaLogicalMonitorLayoutMode;
|
||||
|
||||
/*
|
||||
* MetaCrtcInfo:
|
||||
* MetaCrtcAssignment:
|
||||
*
|
||||
* A representation of a CRTC configuration, generated by
|
||||
* MetaMonitorConfigManager.
|
||||
*/
|
||||
struct _MetaCrtcInfo
|
||||
struct _MetaCrtcAssignment
|
||||
{
|
||||
MetaCrtc *crtc;
|
||||
MetaCrtcMode *mode;
|
||||
@@ -78,12 +78,12 @@ struct _MetaCrtcInfo
|
||||
};
|
||||
|
||||
/*
|
||||
* MetaOutputInfo:
|
||||
* MetaOutputAssignment:
|
||||
*
|
||||
* A representation of a connector configuration, generated by
|
||||
* MetaMonitorConfigManager.
|
||||
*/
|
||||
struct _MetaOutputInfo
|
||||
struct _MetaOutputAssignment
|
||||
{
|
||||
MetaOutput *output;
|
||||
gboolean is_primary;
|
||||
@@ -387,4 +387,22 @@ gboolean meta_monitor_has_aspect_as_size (MetaMonitor *monitor);
|
||||
char * meta_monitor_manager_get_vendor_name (MetaMonitorManager *manager,
|
||||
const char *vendor);
|
||||
|
||||
static inline MetaOutputAssignment *
|
||||
meta_find_output_assignment (MetaOutputAssignment **outputs,
|
||||
unsigned int n_outputs,
|
||||
MetaOutput *output)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
{
|
||||
MetaOutputAssignment *output_assignment = outputs[i];
|
||||
|
||||
if (output == output_assignment->output)
|
||||
return output_assignment;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* META_MONITOR_MANAGER_PRIVATE_H */
|
||||
|
@@ -140,7 +140,10 @@ meta_monitor_manager_set_primary_logical_monitor (MetaMonitorManager *manager,
|
||||
static gboolean
|
||||
is_main_tiled_monitor_output (MetaOutput *output)
|
||||
{
|
||||
return output->tile_info.loc_h_tile == 0 && output->tile_info.loc_v_tile == 0;
|
||||
const MetaOutputInfo *output_info = meta_output_get_info (output);
|
||||
|
||||
return (output_info->tile_info.loc_h_tile == 0 &&
|
||||
output_info->tile_info.loc_v_tile == 0);
|
||||
}
|
||||
|
||||
static MetaLogicalMonitor *
|
||||
@@ -1014,15 +1017,16 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
|
||||
{
|
||||
MetaCrtc *crtc = l->data;
|
||||
GVariantBuilder transforms;
|
||||
MetaCrtcConfig *crtc_config;
|
||||
const MetaCrtcConfig *crtc_config;
|
||||
|
||||
g_variant_builder_init (&transforms, G_VARIANT_TYPE ("au"));
|
||||
for (j = 0; j <= META_MONITOR_TRANSFORM_FLIPPED_270; j++)
|
||||
if (crtc->all_transforms & (1 << j))
|
||||
g_variant_builder_add (&transforms, "u", j);
|
||||
|
||||
crtc_config = crtc->config;
|
||||
{
|
||||
if (meta_crtc_get_all_transforms (crtc) & (1 << j))
|
||||
g_variant_builder_add (&transforms, "u", j);
|
||||
}
|
||||
|
||||
crtc_config = meta_crtc_get_config (crtc);
|
||||
if (crtc_config)
|
||||
{
|
||||
int current_mode_index;
|
||||
@@ -1030,7 +1034,7 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
|
||||
current_mode_index = g_list_index (combined_modes, crtc_config->mode);
|
||||
g_variant_builder_add (&crtc_builder, "(uxiiiiiuaua{sv})",
|
||||
i, /* ID */
|
||||
(int64_t) crtc->crtc_id,
|
||||
(int64_t) meta_crtc_get_id (crtc),
|
||||
(int) roundf (crtc_config->layout.origin.x),
|
||||
(int) roundf (crtc_config->layout.origin.y),
|
||||
(int) roundf (crtc_config->layout.size.width),
|
||||
@@ -1044,7 +1048,7 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
|
||||
{
|
||||
g_variant_builder_add (&crtc_builder, "(uxiiiiiuaua{sv})",
|
||||
i, /* ID */
|
||||
(int64_t) crtc->crtc_id,
|
||||
(int64_t) meta_crtc_get_id (crtc),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
@@ -1059,15 +1063,23 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
|
||||
for (l = combined_outputs, i = 0; l; l = l->next, i++)
|
||||
{
|
||||
MetaOutput *output = l->data;
|
||||
const MetaOutputInfo *output_info = meta_output_get_info (output);
|
||||
GVariantBuilder crtcs, modes, clones, properties;
|
||||
GBytes *edid;
|
||||
MetaCrtc *crtc;
|
||||
int crtc_index;
|
||||
int backlight;
|
||||
int min_backlight_step;
|
||||
gboolean is_primary;
|
||||
gboolean is_presentation;
|
||||
const char * connector_type_name;
|
||||
gboolean is_underscanning;
|
||||
gboolean supports_underscanning;
|
||||
|
||||
g_variant_builder_init (&crtcs, G_VARIANT_TYPE ("au"));
|
||||
for (j = 0; j < output->n_possible_crtcs; j++)
|
||||
for (j = 0; j < output_info->n_possible_crtcs; j++)
|
||||
{
|
||||
MetaCrtc *possible_crtc = output->possible_crtcs[j];
|
||||
MetaCrtc *possible_crtc = output_info->possible_crtcs[j];
|
||||
unsigned possible_crtc_index;
|
||||
|
||||
possible_crtc_index = g_list_index (combined_crtcs, possible_crtc);
|
||||
@@ -1075,52 +1087,62 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
|
||||
}
|
||||
|
||||
g_variant_builder_init (&modes, G_VARIANT_TYPE ("au"));
|
||||
for (j = 0; j < output->n_modes; j++)
|
||||
for (j = 0; j < output_info->n_modes; j++)
|
||||
{
|
||||
unsigned mode_index;
|
||||
|
||||
mode_index = g_list_index (combined_modes, output->modes[j]);
|
||||
mode_index = g_list_index (combined_modes, output_info->modes[j]);
|
||||
g_variant_builder_add (&modes, "u", mode_index);
|
||||
}
|
||||
|
||||
g_variant_builder_init (&clones, G_VARIANT_TYPE ("au"));
|
||||
for (j = 0; j < output->n_possible_clones; j++)
|
||||
for (j = 0; j < output_info->n_possible_clones; j++)
|
||||
{
|
||||
unsigned int possible_clone_index;
|
||||
|
||||
possible_clone_index = g_list_index (combined_outputs,
|
||||
output->possible_clones[j]);
|
||||
output_info->possible_clones[j]);
|
||||
g_variant_builder_add (&clones, "u", possible_clone_index);
|
||||
}
|
||||
|
||||
backlight = meta_output_get_backlight (output);
|
||||
min_backlight_step =
|
||||
output_info->backlight_max - output_info->backlight_min
|
||||
? 100 / (output_info->backlight_max - output_info->backlight_min)
|
||||
: -1;
|
||||
is_primary = meta_output_is_primary (output);
|
||||
is_presentation = meta_output_is_presentation (output);
|
||||
is_underscanning = meta_output_is_underscanning (output);
|
||||
connector_type_name = get_connector_type_name (output_info->connector_type);
|
||||
supports_underscanning = output_info->supports_underscanning;
|
||||
|
||||
g_variant_builder_init (&properties, G_VARIANT_TYPE ("a{sv}"));
|
||||
g_variant_builder_add (&properties, "{sv}", "vendor",
|
||||
g_variant_new_string (output->vendor));
|
||||
g_variant_new_string (output_info->vendor));
|
||||
g_variant_builder_add (&properties, "{sv}", "product",
|
||||
g_variant_new_string (output->product));
|
||||
g_variant_new_string (output_info->product));
|
||||
g_variant_builder_add (&properties, "{sv}", "serial",
|
||||
g_variant_new_string (output->serial));
|
||||
g_variant_new_string (output_info->serial));
|
||||
g_variant_builder_add (&properties, "{sv}", "width-mm",
|
||||
g_variant_new_int32 (output->width_mm));
|
||||
g_variant_new_int32 (output_info->width_mm));
|
||||
g_variant_builder_add (&properties, "{sv}", "height-mm",
|
||||
g_variant_new_int32 (output->height_mm));
|
||||
g_variant_new_int32 (output_info->height_mm));
|
||||
g_variant_builder_add (&properties, "{sv}", "display-name",
|
||||
g_variant_new_string (output->name));
|
||||
g_variant_new_string (output_info->name));
|
||||
g_variant_builder_add (&properties, "{sv}", "backlight",
|
||||
g_variant_new_int32 (output->backlight));
|
||||
g_variant_new_int32 (backlight));
|
||||
g_variant_builder_add (&properties, "{sv}", "min-backlight-step",
|
||||
g_variant_new_int32 ((output->backlight_max - output->backlight_min) ?
|
||||
100 / (output->backlight_max - output->backlight_min) : -1));
|
||||
g_variant_new_int32 (min_backlight_step));
|
||||
g_variant_builder_add (&properties, "{sv}", "primary",
|
||||
g_variant_new_boolean (output->is_primary));
|
||||
g_variant_new_boolean (is_primary));
|
||||
g_variant_builder_add (&properties, "{sv}", "presentation",
|
||||
g_variant_new_boolean (output->is_presentation));
|
||||
g_variant_new_boolean (is_presentation));
|
||||
g_variant_builder_add (&properties, "{sv}", "connector-type",
|
||||
g_variant_new_string (get_connector_type_name (output->connector_type)));
|
||||
g_variant_new_string (connector_type_name));
|
||||
g_variant_builder_add (&properties, "{sv}", "underscanning",
|
||||
g_variant_new_boolean (output->is_underscanning));
|
||||
g_variant_new_boolean (is_underscanning));
|
||||
g_variant_builder_add (&properties, "{sv}", "supports-underscanning",
|
||||
g_variant_new_boolean (output->supports_underscanning));
|
||||
g_variant_new_boolean (supports_underscanning));
|
||||
|
||||
edid = manager_class->read_edid (manager, output);
|
||||
if (edid)
|
||||
@@ -1131,28 +1153,30 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
|
||||
g_bytes_unref (edid);
|
||||
}
|
||||
|
||||
if (output->tile_info.group_id)
|
||||
if (output_info->tile_info.group_id)
|
||||
{
|
||||
g_variant_builder_add (&properties, "{sv}", "tile",
|
||||
g_variant_new ("(uuuuuuuu)",
|
||||
output->tile_info.group_id,
|
||||
output->tile_info.flags,
|
||||
output->tile_info.max_h_tiles,
|
||||
output->tile_info.max_v_tiles,
|
||||
output->tile_info.loc_h_tile,
|
||||
output->tile_info.loc_v_tile,
|
||||
output->tile_info.tile_w,
|
||||
output->tile_info.tile_h));
|
||||
GVariant *tile_variant;
|
||||
|
||||
tile_variant = g_variant_new ("(uuuuuuuu)",
|
||||
output_info->tile_info.group_id,
|
||||
output_info->tile_info.flags,
|
||||
output_info->tile_info.max_h_tiles,
|
||||
output_info->tile_info.max_v_tiles,
|
||||
output_info->tile_info.loc_h_tile,
|
||||
output_info->tile_info.loc_v_tile,
|
||||
output_info->tile_info.tile_w,
|
||||
output_info->tile_info.tile_h);
|
||||
g_variant_builder_add (&properties, "{sv}", "tile", tile_variant);
|
||||
}
|
||||
|
||||
crtc = meta_output_get_assigned_crtc (output);
|
||||
crtc_index = crtc ? g_list_index (combined_crtcs, crtc) : -1;
|
||||
g_variant_builder_add (&output_builder, "(uxiausauaua{sv})",
|
||||
i, /* ID */
|
||||
(gint64)output->winsys_id,
|
||||
meta_output_get_id (output),
|
||||
crtc_index,
|
||||
&crtcs,
|
||||
output->name,
|
||||
meta_output_get_name (output),
|
||||
&modes,
|
||||
&clones,
|
||||
&properties);
|
||||
@@ -1161,14 +1185,16 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
|
||||
for (l = combined_modes, i = 0; l; l = l->next, i++)
|
||||
{
|
||||
MetaCrtcMode *mode = l->data;
|
||||
const MetaCrtcModeInfo *crtc_mode_info =
|
||||
meta_crtc_mode_get_info (mode);;
|
||||
|
||||
g_variant_builder_add (&mode_builder, "(uxuudu)",
|
||||
i, /* ID */
|
||||
(gint64)mode->mode_id,
|
||||
(guint32)mode->width,
|
||||
(guint32)mode->height,
|
||||
(double)mode->refresh_rate,
|
||||
(guint32)mode->flags);
|
||||
(int64_t) meta_crtc_mode_get_id (mode),
|
||||
(uint32_t) crtc_mode_info->width,
|
||||
(uint32_t) crtc_mode_info->height,
|
||||
(double) crtc_mode_info->refresh_rate,
|
||||
(uint32_t) crtc_mode_info->flags);
|
||||
}
|
||||
|
||||
if (!meta_monitor_manager_get_max_screen_size (manager,
|
||||
@@ -2103,6 +2129,8 @@ meta_monitor_manager_handle_change_backlight (MetaDBusDisplayConfig *skeleton,
|
||||
{
|
||||
GList *combined_outputs;
|
||||
MetaOutput *output;
|
||||
const MetaOutputInfo *output_info;
|
||||
int new_backlight;
|
||||
|
||||
if (serial != manager->serial)
|
||||
{
|
||||
@@ -2133,8 +2161,10 @@ meta_monitor_manager_handle_change_backlight (MetaDBusDisplayConfig *skeleton,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (output->backlight == -1 ||
|
||||
(output->backlight_min == 0 && output->backlight_max == 0))
|
||||
output_info = meta_output_get_info (output);
|
||||
if (meta_output_get_backlight (output) == -1 ||
|
||||
(output_info->backlight_min == 0 &&
|
||||
output_info->backlight_max == 0))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_INVALID_ARGS,
|
||||
@@ -2144,7 +2174,10 @@ meta_monitor_manager_handle_change_backlight (MetaDBusDisplayConfig *skeleton,
|
||||
|
||||
META_MONITOR_MANAGER_GET_CLASS (manager)->change_backlight (manager, output, value);
|
||||
|
||||
meta_dbus_display_config_complete_change_backlight (skeleton, invocation, output->backlight);
|
||||
new_backlight = meta_output_get_backlight (output);
|
||||
meta_dbus_display_config_complete_change_backlight (skeleton,
|
||||
invocation,
|
||||
new_backlight);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -2649,8 +2682,9 @@ rebuild_monitors (MetaMonitorManager *manager)
|
||||
for (k = meta_gpu_get_outputs (gpu); k; k = k->next)
|
||||
{
|
||||
MetaOutput *output = k->data;
|
||||
const MetaOutputInfo *output_info = meta_output_get_info (output);
|
||||
|
||||
if (output->tile_info.group_id)
|
||||
if (output_info->tile_info.group_id)
|
||||
{
|
||||
if (is_main_tiled_monitor_output (output))
|
||||
{
|
||||
@@ -2882,8 +2916,8 @@ meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager,
|
||||
}
|
||||
|
||||
void
|
||||
meta_output_parse_edid (MetaOutput *output,
|
||||
GBytes *edid)
|
||||
meta_output_info_parse_edid (MetaOutputInfo *output_info,
|
||||
GBytes *edid)
|
||||
{
|
||||
MonitorInfo *parsed_edid;
|
||||
gsize len;
|
||||
@@ -2895,43 +2929,44 @@ meta_output_parse_edid (MetaOutput *output,
|
||||
|
||||
if (parsed_edid)
|
||||
{
|
||||
output->vendor = g_strndup (parsed_edid->manufacturer_code, 4);
|
||||
if (!g_utf8_validate (output->vendor, -1, NULL))
|
||||
g_clear_pointer (&output->vendor, g_free);
|
||||
output_info->vendor = g_strndup (parsed_edid->manufacturer_code, 4);
|
||||
if (!g_utf8_validate (output_info->vendor, -1, NULL))
|
||||
g_clear_pointer (&output_info->vendor, g_free);
|
||||
|
||||
output->product = g_strndup (parsed_edid->dsc_product_name, 14);
|
||||
if (!g_utf8_validate (output->product, -1, NULL) ||
|
||||
output->product[0] == '\0')
|
||||
output_info->product = g_strndup (parsed_edid->dsc_product_name, 14);
|
||||
if (!g_utf8_validate (output_info->product, -1, NULL) ||
|
||||
output_info->product[0] == '\0')
|
||||
{
|
||||
g_clear_pointer (&output->product, g_free);
|
||||
output->product = g_strdup_printf ("0x%04x", (unsigned) parsed_edid->product_code);
|
||||
g_clear_pointer (&output_info->product, g_free);
|
||||
output_info->product = g_strdup_printf ("0x%04x", (unsigned) parsed_edid->product_code);
|
||||
}
|
||||
|
||||
output->serial = g_strndup (parsed_edid->dsc_serial_number, 14);
|
||||
if (!g_utf8_validate (output->serial, -1, NULL) ||
|
||||
output->serial[0] == '\0')
|
||||
output_info->serial = g_strndup (parsed_edid->dsc_serial_number, 14);
|
||||
if (!g_utf8_validate (output_info->serial, -1, NULL) ||
|
||||
output_info->serial[0] == '\0')
|
||||
{
|
||||
g_clear_pointer (&output->serial, g_free);
|
||||
output->serial = g_strdup_printf ("0x%08x", parsed_edid->serial_number);
|
||||
g_clear_pointer (&output_info->serial, g_free);
|
||||
output_info->serial = g_strdup_printf ("0x%08x", parsed_edid->serial_number);
|
||||
}
|
||||
|
||||
g_free (parsed_edid);
|
||||
}
|
||||
|
||||
out:
|
||||
if (!output->vendor)
|
||||
output->vendor = g_strdup ("unknown");
|
||||
if (!output->product)
|
||||
output->product = g_strdup ("unknown");
|
||||
if (!output->serial)
|
||||
output->serial = g_strdup ("unknown");
|
||||
if (!output_info->vendor)
|
||||
output_info->vendor = g_strdup ("unknown");
|
||||
if (!output_info->product)
|
||||
output_info->product = g_strdup ("unknown");
|
||||
if (!output_info->serial)
|
||||
output_info->serial = g_strdup ("unknown");
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_output_is_laptop (MetaOutput *output)
|
||||
{
|
||||
/* FIXME: extend with better heuristics */
|
||||
switch (output->connector_type)
|
||||
const MetaOutputInfo *output_info = meta_output_get_info (output);
|
||||
|
||||
switch (output_info->connector_type)
|
||||
{
|
||||
case META_CONNECTOR_TYPE_eDP:
|
||||
case META_CONNECTOR_TYPE_LVDS:
|
||||
|
@@ -36,6 +36,7 @@ enum _MetaMonitorTransform
|
||||
META_MONITOR_TRANSFORM_FLIPPED_270,
|
||||
};
|
||||
#define META_MONITOR_N_TRANSFORMS (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)
|
||||
#define META_MONITOR_ALL_TRANSFORMS ((1 << META_MONITOR_N_TRANSFORMS) - 1)
|
||||
|
||||
/* Returns true if transform causes width and height to be inverted
|
||||
This is true for the odd transforms in the enum */
|
||||
|
@@ -168,19 +168,28 @@ meta_monitor_spec_free (MetaMonitorSpec *monitor_spec)
|
||||
g_free (monitor_spec);
|
||||
}
|
||||
|
||||
static const MetaOutputInfo *
|
||||
meta_monitor_get_main_output_info (MetaMonitor *monitor)
|
||||
{
|
||||
MetaOutput *output = meta_monitor_get_main_output (monitor);
|
||||
|
||||
return meta_output_get_info (output);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_generate_spec (MetaMonitor *monitor)
|
||||
{
|
||||
MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor);
|
||||
MetaOutput *output = meta_monitor_get_main_output (monitor);
|
||||
const MetaOutputInfo *output_info =
|
||||
meta_monitor_get_main_output_info (monitor);
|
||||
MetaMonitorSpec *monitor_spec;
|
||||
|
||||
monitor_spec = g_new0 (MetaMonitorSpec, 1);
|
||||
*monitor_spec = (MetaMonitorSpec) {
|
||||
.connector = g_strdup (output->name),
|
||||
.vendor = g_strdup (output->vendor),
|
||||
.product = g_strdup (output->product),
|
||||
.serial = g_strdup (output->serial),
|
||||
.connector = g_strdup (output_info->name),
|
||||
.vendor = g_strdup (output_info->vendor),
|
||||
.product = g_strdup (output_info->product),
|
||||
.serial = g_strdup (output_info->serial),
|
||||
};
|
||||
|
||||
priv->spec = monitor_spec;
|
||||
@@ -316,17 +325,16 @@ meta_monitor_is_primary (MetaMonitor *monitor)
|
||||
|
||||
output = meta_monitor_get_main_output (monitor);
|
||||
|
||||
return output->is_primary;
|
||||
return meta_output_is_primary (output);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_monitor_supports_underscanning (MetaMonitor *monitor)
|
||||
{
|
||||
MetaOutput *output;
|
||||
const MetaOutputInfo *output_info =
|
||||
meta_monitor_get_main_output_info (monitor);
|
||||
|
||||
output = meta_monitor_get_main_output (monitor);
|
||||
|
||||
return output->supports_underscanning;
|
||||
return output_info->supports_underscanning;
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -336,17 +344,16 @@ meta_monitor_is_underscanning (MetaMonitor *monitor)
|
||||
|
||||
output = meta_monitor_get_main_output (monitor);
|
||||
|
||||
return output->is_underscanning;
|
||||
return meta_output_is_underscanning (output);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_monitor_is_laptop_panel (MetaMonitor *monitor)
|
||||
{
|
||||
MetaOutput *output;
|
||||
const MetaOutputInfo *output_info =
|
||||
meta_monitor_get_main_output_info (monitor);
|
||||
|
||||
output = meta_monitor_get_main_output (monitor);
|
||||
|
||||
switch (output->connector_type)
|
||||
switch (output_info->connector_type)
|
||||
{
|
||||
case META_CONNECTOR_TYPE_eDP:
|
||||
case META_CONNECTOR_TYPE_LVDS:
|
||||
@@ -392,65 +399,65 @@ meta_monitor_get_physical_dimensions (MetaMonitor *monitor,
|
||||
int *width_mm,
|
||||
int *height_mm)
|
||||
{
|
||||
MetaOutput *output;
|
||||
const MetaOutputInfo *output_info =
|
||||
meta_monitor_get_main_output_info (monitor);
|
||||
|
||||
output = meta_monitor_get_main_output (monitor);
|
||||
*width_mm = output->width_mm;
|
||||
*height_mm = output->height_mm;
|
||||
*width_mm = output_info->width_mm;
|
||||
*height_mm = output_info->height_mm;
|
||||
}
|
||||
|
||||
CoglSubpixelOrder
|
||||
meta_monitor_get_subpixel_order (MetaMonitor *monitor)
|
||||
{
|
||||
MetaOutput *output;
|
||||
const MetaOutputInfo *output_info =
|
||||
meta_monitor_get_main_output_info (monitor);
|
||||
|
||||
output = meta_monitor_get_main_output (monitor);
|
||||
return output->subpixel_order;
|
||||
return output_info->subpixel_order;
|
||||
}
|
||||
|
||||
const char *
|
||||
meta_monitor_get_connector (MetaMonitor *monitor)
|
||||
{
|
||||
MetaOutput *output;
|
||||
const MetaOutputInfo *output_info =
|
||||
meta_monitor_get_main_output_info (monitor);
|
||||
|
||||
output = meta_monitor_get_main_output (monitor);
|
||||
return output->name;
|
||||
return output_info->name;
|
||||
}
|
||||
|
||||
const char *
|
||||
meta_monitor_get_vendor (MetaMonitor *monitor)
|
||||
{
|
||||
MetaOutput *output;
|
||||
const MetaOutputInfo *output_info =
|
||||
meta_monitor_get_main_output_info (monitor);
|
||||
|
||||
output = meta_monitor_get_main_output (monitor);
|
||||
return output->vendor;
|
||||
return output_info->vendor;
|
||||
}
|
||||
|
||||
const char *
|
||||
meta_monitor_get_product (MetaMonitor *monitor)
|
||||
{
|
||||
MetaOutput *output;
|
||||
const MetaOutputInfo *output_info =
|
||||
meta_monitor_get_main_output_info (monitor);
|
||||
|
||||
output = meta_monitor_get_main_output (monitor);
|
||||
return output->product;
|
||||
return output_info->product;
|
||||
}
|
||||
|
||||
const char *
|
||||
meta_monitor_get_serial (MetaMonitor *monitor)
|
||||
{
|
||||
MetaOutput *output;
|
||||
const MetaOutputInfo *output_info =
|
||||
meta_monitor_get_main_output_info (monitor);
|
||||
|
||||
output = meta_monitor_get_main_output (monitor);
|
||||
return output->serial;
|
||||
return output_info->serial;
|
||||
}
|
||||
|
||||
MetaConnectorType
|
||||
meta_monitor_get_connector_type (MetaMonitor *monitor)
|
||||
{
|
||||
MetaOutput *output;
|
||||
const MetaOutputInfo *output_info =
|
||||
meta_monitor_get_main_output_info (monitor);
|
||||
|
||||
output = meta_monitor_get_main_output (monitor);
|
||||
return output->connector_type;
|
||||
return output_info->connector_type;
|
||||
}
|
||||
|
||||
MetaMonitorTransform
|
||||
@@ -562,9 +569,12 @@ meta_monitor_create_spec (MetaMonitor *monitor,
|
||||
int height,
|
||||
MetaCrtcMode *crtc_mode)
|
||||
{
|
||||
MetaOutput *output = meta_monitor_get_main_output (monitor);
|
||||
const MetaOutputInfo *output_info =
|
||||
meta_monitor_get_main_output_info (monitor);
|
||||
const MetaCrtcModeInfo *crtc_mode_info =
|
||||
meta_crtc_mode_get_info (crtc_mode);
|
||||
|
||||
if (meta_monitor_transform_is_rotated (output->panel_orientation_transform))
|
||||
if (meta_monitor_transform_is_rotated (output_info->panel_orientation_transform))
|
||||
{
|
||||
int temp = width;
|
||||
width = height;
|
||||
@@ -574,8 +584,8 @@ meta_monitor_create_spec (MetaMonitor *monitor,
|
||||
return (MetaMonitorModeSpec) {
|
||||
.width = width,
|
||||
.height = height,
|
||||
.refresh_rate = crtc_mode->refresh_rate,
|
||||
.flags = crtc_mode->flags & HANDLED_CRTC_MODE_FLAGS
|
||||
.refresh_rate = crtc_mode_info->refresh_rate,
|
||||
.flags = crtc_mode_info->flags & HANDLED_CRTC_MODE_FLAGS
|
||||
};
|
||||
}
|
||||
|
||||
@@ -586,15 +596,21 @@ meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal)
|
||||
MetaMonitorPrivate *monitor_priv =
|
||||
meta_monitor_get_instance_private (monitor);
|
||||
MetaOutput *output;
|
||||
const MetaOutputInfo *output_info;
|
||||
MetaCrtcMode *preferred_mode;
|
||||
MetaCrtcModeFlag preferred_mode_flags;
|
||||
unsigned int i;
|
||||
|
||||
output = meta_monitor_get_main_output (monitor);
|
||||
preferred_mode_flags = output->preferred_mode->flags;
|
||||
output_info = meta_output_get_info (output);
|
||||
preferred_mode = output_info->preferred_mode;
|
||||
preferred_mode_flags = meta_crtc_mode_get_info (preferred_mode)->flags;
|
||||
|
||||
for (i = 0; i < output->n_modes; i++)
|
||||
for (i = 0; i < output_info->n_modes; i++)
|
||||
{
|
||||
MetaCrtcMode *crtc_mode = output->modes[i];
|
||||
MetaCrtcMode *crtc_mode = output_info->modes[i];
|
||||
const MetaCrtcModeInfo *crtc_mode_info =
|
||||
meta_crtc_mode_get_info (crtc_mode);
|
||||
MetaCrtc *crtc;
|
||||
MetaMonitorMode *mode;
|
||||
gboolean replace;
|
||||
@@ -602,8 +618,8 @@ meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal)
|
||||
mode = g_new0 (MetaMonitorMode, 1);
|
||||
mode->monitor = monitor;
|
||||
mode->spec = meta_monitor_create_spec (monitor,
|
||||
crtc_mode->width,
|
||||
crtc_mode->height,
|
||||
crtc_mode_info->width,
|
||||
crtc_mode_info->height,
|
||||
crtc_mode);
|
||||
mode->id = generate_mode_id (&mode->spec);
|
||||
mode->crtc_modes = g_new (MetaMonitorCrtcMode, 1);
|
||||
@@ -619,21 +635,27 @@ meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal)
|
||||
* otherwise take the first one in the list. This guarantees that the
|
||||
* preferred mode is always added.
|
||||
*/
|
||||
replace = crtc_mode->flags == preferred_mode_flags;
|
||||
replace = crtc_mode_info->flags == preferred_mode_flags;
|
||||
|
||||
if (!meta_monitor_add_mode (monitor, mode, replace))
|
||||
{
|
||||
g_assert (crtc_mode != output->preferred_mode);
|
||||
g_assert (crtc_mode != output_info->preferred_mode);
|
||||
meta_monitor_mode_free (mode);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (crtc_mode == output->preferred_mode)
|
||||
if (crtc_mode == output_info->preferred_mode)
|
||||
monitor_priv->preferred_mode = mode;
|
||||
|
||||
crtc = meta_output_get_assigned_crtc (output);
|
||||
if (crtc && crtc->config && crtc_mode == crtc->config->mode)
|
||||
monitor_priv->current_mode = mode;
|
||||
if (crtc)
|
||||
{
|
||||
const MetaCrtcConfig *crtc_config;
|
||||
|
||||
crtc_config = meta_crtc_get_config (crtc);
|
||||
if (crtc_config && crtc_mode == crtc_config->mode)
|
||||
monitor_priv->current_mode = mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -653,7 +675,7 @@ meta_monitor_normal_new (MetaGpu *gpu,
|
||||
monitor_priv->gpu = gpu;
|
||||
|
||||
monitor_priv->outputs = g_list_append (NULL, g_object_ref (output));
|
||||
monitor_priv->winsys_id = output->winsys_id;
|
||||
monitor_priv->winsys_id = meta_output_get_id (output);
|
||||
meta_monitor_generate_spec (monitor);
|
||||
|
||||
meta_monitor_normal_generate_modes (monitor_normal);
|
||||
@@ -679,11 +701,11 @@ meta_monitor_normal_derive_layout (MetaMonitor *monitor,
|
||||
{
|
||||
MetaOutput *output;
|
||||
MetaCrtc *crtc;
|
||||
MetaCrtcConfig *crtc_config;
|
||||
const MetaCrtcConfig *crtc_config;
|
||||
|
||||
output = meta_monitor_get_main_output (monitor);
|
||||
crtc = meta_output_get_assigned_crtc (output);
|
||||
crtc_config = crtc->config;
|
||||
crtc_config = meta_crtc_get_config (crtc);
|
||||
|
||||
g_return_if_fail (crtc_config);
|
||||
|
||||
@@ -697,14 +719,17 @@ meta_monitor_normal_get_suggested_position (MetaMonitor *monitor,
|
||||
int *x,
|
||||
int *y)
|
||||
{
|
||||
MetaOutput *output;
|
||||
const MetaOutputInfo *output_info =
|
||||
meta_monitor_get_main_output_info (monitor);
|
||||
|
||||
output = meta_monitor_get_main_output (monitor);
|
||||
if (output->suggested_x < 0 && output->suggested_y < 0)
|
||||
if (!output_info->hotplug_mode_update)
|
||||
return FALSE;
|
||||
|
||||
*x = output->suggested_x;
|
||||
*y = output->suggested_y;
|
||||
if (output_info->suggested_x < 0 && output_info->suggested_y < 0)
|
||||
return FALSE;
|
||||
|
||||
*x = output_info->suggested_x;
|
||||
*y = output_info->suggested_y;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -765,12 +790,15 @@ add_tiled_monitor_outputs (MetaGpu *gpu,
|
||||
for (l = outputs; l; l = l->next)
|
||||
{
|
||||
MetaOutput *output = l->data;
|
||||
const MetaOutputInfo *output_info = meta_output_get_info (output);
|
||||
const MetaOutputInfo *origin_output_info;
|
||||
|
||||
if (output->tile_info.group_id != monitor_tiled->tile_group_id)
|
||||
if (output_info->tile_info.group_id != monitor_tiled->tile_group_id)
|
||||
continue;
|
||||
|
||||
g_warn_if_fail (output->subpixel_order ==
|
||||
monitor_tiled->origin_output->subpixel_order);
|
||||
origin_output_info = meta_output_get_info (monitor_tiled->origin_output);
|
||||
g_warn_if_fail (output_info->subpixel_order ==
|
||||
origin_output_info->subpixel_order);
|
||||
|
||||
monitor_priv->outputs = g_list_append (monitor_priv->outputs,
|
||||
g_object_ref (output));
|
||||
@@ -786,51 +814,68 @@ calculate_tile_coordinate (MetaMonitor *monitor,
|
||||
{
|
||||
MetaMonitorPrivate *monitor_priv =
|
||||
meta_monitor_get_instance_private (monitor);
|
||||
const MetaOutputInfo *output_info = meta_output_get_info (output);
|
||||
GList *l;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
||||
for (l = monitor_priv->outputs; l; l = l->next)
|
||||
{
|
||||
MetaOutput *other_output = l->data;
|
||||
const MetaOutputInfo *other_output_info = meta_output_get_info (l->data);
|
||||
|
||||
switch (crtc_transform)
|
||||
{
|
||||
case META_MONITOR_TRANSFORM_NORMAL:
|
||||
case META_MONITOR_TRANSFORM_FLIPPED:
|
||||
if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile &&
|
||||
other_output->tile_info.loc_h_tile < output->tile_info.loc_h_tile)
|
||||
x += other_output->tile_info.tile_w;
|
||||
if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile &&
|
||||
other_output->tile_info.loc_v_tile < output->tile_info.loc_v_tile)
|
||||
y += other_output->tile_info.tile_h;
|
||||
if ((other_output_info->tile_info.loc_v_tile ==
|
||||
output_info->tile_info.loc_v_tile) &&
|
||||
(other_output_info->tile_info.loc_h_tile <
|
||||
output_info->tile_info.loc_h_tile))
|
||||
x += other_output_info->tile_info.tile_w;
|
||||
if ((other_output_info->tile_info.loc_h_tile ==
|
||||
output_info->tile_info.loc_h_tile) &&
|
||||
(other_output_info->tile_info.loc_v_tile <
|
||||
output_info->tile_info.loc_v_tile))
|
||||
y += other_output_info->tile_info.tile_h;
|
||||
break;
|
||||
case META_MONITOR_TRANSFORM_180:
|
||||
case META_MONITOR_TRANSFORM_FLIPPED_180:
|
||||
if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile &&
|
||||
other_output->tile_info.loc_h_tile > output->tile_info.loc_h_tile)
|
||||
x += other_output->tile_info.tile_w;
|
||||
if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile &&
|
||||
other_output->tile_info.loc_v_tile > output->tile_info.loc_v_tile)
|
||||
y += other_output->tile_info.tile_h;
|
||||
if ((other_output_info->tile_info.loc_v_tile ==
|
||||
output_info->tile_info.loc_v_tile) &&
|
||||
(other_output_info->tile_info.loc_h_tile >
|
||||
output_info->tile_info.loc_h_tile))
|
||||
x += other_output_info->tile_info.tile_w;
|
||||
if ((other_output_info->tile_info.loc_h_tile ==
|
||||
output_info->tile_info.loc_h_tile) &&
|
||||
(other_output_info->tile_info.loc_v_tile >
|
||||
output_info->tile_info.loc_v_tile))
|
||||
y += other_output_info->tile_info.tile_h;
|
||||
break;
|
||||
case META_MONITOR_TRANSFORM_270:
|
||||
case META_MONITOR_TRANSFORM_FLIPPED_270:
|
||||
if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile &&
|
||||
other_output->tile_info.loc_h_tile > output->tile_info.loc_h_tile)
|
||||
y += other_output->tile_info.tile_w;
|
||||
if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile &&
|
||||
other_output->tile_info.loc_v_tile > output->tile_info.loc_v_tile)
|
||||
x += other_output->tile_info.tile_h;
|
||||
if ((other_output_info->tile_info.loc_v_tile ==
|
||||
output_info->tile_info.loc_v_tile) &&
|
||||
(other_output_info->tile_info.loc_h_tile >
|
||||
output_info->tile_info.loc_h_tile))
|
||||
y += other_output_info->tile_info.tile_w;
|
||||
if ((other_output_info->tile_info.loc_h_tile ==
|
||||
output_info->tile_info.loc_h_tile) &&
|
||||
(other_output_info->tile_info.loc_v_tile >
|
||||
output_info->tile_info.loc_v_tile))
|
||||
x += other_output_info->tile_info.tile_h;
|
||||
break;
|
||||
case META_MONITOR_TRANSFORM_90:
|
||||
case META_MONITOR_TRANSFORM_FLIPPED_90:
|
||||
if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile &&
|
||||
other_output->tile_info.loc_h_tile < output->tile_info.loc_h_tile)
|
||||
y += other_output->tile_info.tile_w;
|
||||
if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile &&
|
||||
other_output->tile_info.loc_v_tile < output->tile_info.loc_v_tile)
|
||||
x += other_output->tile_info.tile_h;
|
||||
if ((other_output_info->tile_info.loc_v_tile ==
|
||||
output_info->tile_info.loc_v_tile) &&
|
||||
(other_output_info->tile_info.loc_h_tile <
|
||||
output_info->tile_info.loc_h_tile))
|
||||
y += other_output_info->tile_info.tile_w;
|
||||
if ((other_output_info->tile_info.loc_h_tile ==
|
||||
output_info->tile_info.loc_h_tile) &&
|
||||
(other_output_info->tile_info.loc_v_tile <
|
||||
output_info->tile_info.loc_v_tile))
|
||||
x += other_output_info->tile_info.tile_h;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -854,13 +899,13 @@ meta_monitor_tiled_calculate_tiled_size (MetaMonitor *monitor,
|
||||
height = 0;
|
||||
for (l = monitor_priv->outputs; l; l = l->next)
|
||||
{
|
||||
MetaOutput *output = l->data;
|
||||
const MetaOutputInfo *output_info = meta_output_get_info (l->data);
|
||||
|
||||
if (output->tile_info.loc_v_tile == 0)
|
||||
width += output->tile_info.tile_w;
|
||||
if (output_info->tile_info.loc_v_tile == 0)
|
||||
width += output_info->tile_info.tile_w;
|
||||
|
||||
if (output->tile_info.loc_h_tile == 0)
|
||||
height += output->tile_info.tile_h;
|
||||
if (output_info->tile_info.loc_h_tile == 0)
|
||||
height += output_info->tile_info.tile_h;
|
||||
}
|
||||
|
||||
*out_width = width;
|
||||
@@ -880,11 +925,14 @@ is_monitor_mode_assigned (MetaMonitor *monitor,
|
||||
MetaOutput *output = l->data;
|
||||
MetaMonitorCrtcMode *monitor_crtc_mode = &mode->crtc_modes[i];
|
||||
MetaCrtc *crtc;
|
||||
const MetaCrtcConfig *crtc_config;
|
||||
|
||||
crtc = meta_output_get_assigned_crtc (output);
|
||||
crtc_config = crtc ? meta_crtc_get_config (crtc) : NULL;
|
||||
|
||||
if (monitor_crtc_mode->crtc_mode &&
|
||||
(!crtc || !crtc->config ||
|
||||
crtc->config->mode != monitor_crtc_mode->crtc_mode))
|
||||
(!crtc || !crtc_config ||
|
||||
crtc_config->mode != monitor_crtc_mode->crtc_mode))
|
||||
return FALSE;
|
||||
else if (!monitor_crtc_mode->crtc_mode && crtc)
|
||||
return FALSE;
|
||||
@@ -897,32 +945,41 @@ static gboolean
|
||||
is_crtc_mode_tiled (MetaOutput *output,
|
||||
MetaCrtcMode *crtc_mode)
|
||||
{
|
||||
return (crtc_mode->width == (int) output->tile_info.tile_w &&
|
||||
crtc_mode->height == (int) output->tile_info.tile_h);
|
||||
const MetaOutputInfo *output_info = meta_output_get_info (output);
|
||||
const MetaCrtcModeInfo *crtc_mode_info = meta_crtc_mode_get_info (crtc_mode);
|
||||
|
||||
return (crtc_mode_info->width == (int) output_info->tile_info.tile_w &&
|
||||
crtc_mode_info->height == (int) output_info->tile_info.tile_h);
|
||||
}
|
||||
|
||||
static MetaCrtcMode *
|
||||
find_tiled_crtc_mode (MetaOutput *output,
|
||||
MetaCrtcMode *reference_crtc_mode)
|
||||
{
|
||||
const MetaOutputInfo *output_info = meta_output_get_info (output);
|
||||
const MetaCrtcModeInfo *reference_crtc_mode_info =
|
||||
meta_crtc_mode_get_info (reference_crtc_mode);
|
||||
MetaCrtcMode *crtc_mode;
|
||||
unsigned int i;
|
||||
|
||||
crtc_mode = output->preferred_mode;
|
||||
crtc_mode = output_info->preferred_mode;
|
||||
if (is_crtc_mode_tiled (output, crtc_mode))
|
||||
return crtc_mode;
|
||||
|
||||
for (i = 0; i < output->n_modes; i++)
|
||||
for (i = 0; i < output_info->n_modes; i++)
|
||||
{
|
||||
crtc_mode = output->modes[i];
|
||||
const MetaCrtcModeInfo *crtc_mode_info;
|
||||
|
||||
crtc_mode = output_info->modes[i];
|
||||
crtc_mode_info = meta_crtc_mode_get_info (crtc_mode);
|
||||
|
||||
if (!is_crtc_mode_tiled (output, crtc_mode))
|
||||
continue;
|
||||
|
||||
if (crtc_mode->refresh_rate != reference_crtc_mode->refresh_rate)
|
||||
if (crtc_mode_info->refresh_rate != reference_crtc_mode_info->refresh_rate)
|
||||
continue;
|
||||
|
||||
if (crtc_mode->flags != reference_crtc_mode->flags)
|
||||
if (crtc_mode_info->flags != reference_crtc_mode_info->flags)
|
||||
continue;
|
||||
|
||||
return crtc_mode;
|
||||
@@ -958,12 +1015,13 @@ create_tiled_monitor_mode (MetaMonitorTiled *monitor_tiled,
|
||||
for (l = monitor_priv->outputs, i = 0; l; l = l->next, i++)
|
||||
{
|
||||
MetaOutput *output = l->data;
|
||||
const MetaOutputInfo *output_info = meta_output_get_info (output);
|
||||
MetaCrtcMode *tiled_crtc_mode;
|
||||
|
||||
tiled_crtc_mode = find_tiled_crtc_mode (output, reference_crtc_mode);
|
||||
if (!tiled_crtc_mode)
|
||||
{
|
||||
g_warning ("No tiled mode found on %s", output->name);
|
||||
g_warning ("No tiled mode found on %s", meta_output_get_name (output));
|
||||
meta_monitor_mode_free ((MetaMonitorMode *) mode);
|
||||
return NULL;
|
||||
}
|
||||
@@ -973,7 +1031,8 @@ create_tiled_monitor_mode (MetaMonitorTiled *monitor_tiled,
|
||||
.crtc_mode = tiled_crtc_mode
|
||||
};
|
||||
|
||||
is_preferred = is_preferred && tiled_crtc_mode == output->preferred_mode;
|
||||
is_preferred = (is_preferred &&
|
||||
tiled_crtc_mode == output_info->preferred_mode);
|
||||
}
|
||||
|
||||
*out_is_preferred = is_preferred;
|
||||
@@ -988,16 +1047,18 @@ generate_tiled_monitor_modes (MetaMonitorTiled *monitor_tiled)
|
||||
MetaMonitorPrivate *monitor_priv =
|
||||
meta_monitor_get_instance_private (monitor);
|
||||
MetaOutput *main_output;
|
||||
const MetaOutputInfo *main_output_info;
|
||||
GList *tiled_modes = NULL;
|
||||
unsigned int i;
|
||||
MetaMonitorMode *best_mode = NULL;
|
||||
GList *l;
|
||||
|
||||
main_output = meta_monitor_get_main_output (META_MONITOR (monitor_tiled));
|
||||
main_output_info = meta_output_get_info (main_output);
|
||||
|
||||
for (i = 0; i < main_output->n_modes; i++)
|
||||
for (i = 0; i < main_output_info->n_modes; i++)
|
||||
{
|
||||
MetaCrtcMode *reference_crtc_mode = main_output->modes[i];
|
||||
MetaCrtcMode *reference_crtc_mode = main_output_info->modes[i];
|
||||
MetaMonitorMode *mode;
|
||||
gboolean is_preferred;
|
||||
|
||||
@@ -1051,6 +1112,7 @@ create_untiled_monitor_mode (MetaMonitorTiled *monitor_tiled,
|
||||
MetaMonitorPrivate *monitor_priv =
|
||||
meta_monitor_get_instance_private (monitor);
|
||||
MetaMonitorModeTiled *mode;
|
||||
const MetaCrtcModeInfo *crtc_mode_info;
|
||||
GList *l;
|
||||
int i;
|
||||
|
||||
@@ -1060,9 +1122,11 @@ create_untiled_monitor_mode (MetaMonitorTiled *monitor_tiled,
|
||||
mode = g_new0 (MetaMonitorModeTiled, 1);
|
||||
mode->is_tiled = FALSE;
|
||||
mode->parent.monitor = monitor;
|
||||
|
||||
crtc_mode_info = meta_crtc_mode_get_info (crtc_mode);
|
||||
mode->parent.spec = meta_monitor_create_spec (monitor,
|
||||
crtc_mode->width,
|
||||
crtc_mode->height,
|
||||
crtc_mode_info->width,
|
||||
crtc_mode_info->height,
|
||||
crtc_mode);
|
||||
mode->parent.id = generate_mode_id (&mode->parent.spec);
|
||||
mode->parent.crtc_modes = g_new0 (MetaMonitorCrtcMode,
|
||||
@@ -1094,13 +1158,14 @@ create_untiled_monitor_mode (MetaMonitorTiled *monitor_tiled,
|
||||
static int
|
||||
count_untiled_crtc_modes (MetaOutput *output)
|
||||
{
|
||||
const MetaOutputInfo *output_info = meta_output_get_info (output);
|
||||
int count;
|
||||
unsigned int i;
|
||||
|
||||
count = 0;
|
||||
for (i = 0; i < output->n_modes; i++)
|
||||
for (i = 0; i < output_info->n_modes; i++)
|
||||
{
|
||||
MetaCrtcMode *crtc_mode = output->modes[i];
|
||||
MetaCrtcMode *crtc_mode = output_info->modes[i];
|
||||
|
||||
if (!is_crtc_mode_tiled (output, crtc_mode))
|
||||
count++;
|
||||
@@ -1149,13 +1214,15 @@ generate_untiled_monitor_modes (MetaMonitorTiled *monitor_tiled)
|
||||
MetaMonitorPrivate *monitor_priv =
|
||||
meta_monitor_get_instance_private (monitor);
|
||||
MetaOutput *main_output;
|
||||
const MetaOutputInfo *main_output_info;
|
||||
unsigned int i;
|
||||
|
||||
main_output = meta_monitor_get_main_output (monitor);
|
||||
main_output_info = meta_output_get_info (main_output);
|
||||
|
||||
for (i = 0; i < main_output->n_modes; i++)
|
||||
for (i = 0; i < main_output_info->n_modes; i++)
|
||||
{
|
||||
MetaCrtcMode *crtc_mode = main_output->modes[i];
|
||||
MetaCrtcMode *crtc_mode = main_output_info->modes[i];
|
||||
MetaMonitorMode *mode;
|
||||
|
||||
mode = create_untiled_monitor_mode (monitor_tiled,
|
||||
@@ -1177,7 +1244,7 @@ generate_untiled_monitor_modes (MetaMonitorTiled *monitor_tiled)
|
||||
}
|
||||
|
||||
if (!monitor_priv->preferred_mode &&
|
||||
crtc_mode == main_output->preferred_mode)
|
||||
crtc_mode == main_output_info->preferred_mode)
|
||||
monitor_priv->preferred_mode = mode;
|
||||
}
|
||||
}
|
||||
@@ -1281,6 +1348,7 @@ meta_monitor_tiled_new (MetaGpu *gpu,
|
||||
MetaMonitorManager *monitor_manager,
|
||||
MetaOutput *output)
|
||||
{
|
||||
const MetaOutputInfo *output_info = meta_output_get_info (output);
|
||||
MetaMonitorTiled *monitor_tiled;
|
||||
MetaMonitor *monitor;
|
||||
MetaMonitorPrivate *monitor_priv;
|
||||
@@ -1291,8 +1359,8 @@ meta_monitor_tiled_new (MetaGpu *gpu,
|
||||
|
||||
monitor_priv->gpu = gpu;
|
||||
|
||||
monitor_tiled->tile_group_id = output->tile_info.group_id;
|
||||
monitor_priv->winsys_id = output->winsys_id;
|
||||
monitor_tiled->tile_group_id = output_info->tile_info.group_id;
|
||||
monitor_priv->winsys_id = meta_output_get_id (output);
|
||||
|
||||
monitor_tiled->origin_output = output;
|
||||
add_tiled_monitor_outputs (gpu, monitor_tiled);
|
||||
@@ -1338,14 +1406,14 @@ meta_monitor_tiled_derive_layout (MetaMonitor *monitor,
|
||||
{
|
||||
MetaOutput *output = l->data;
|
||||
MetaCrtc *crtc;
|
||||
MetaCrtcConfig *crtc_config;
|
||||
graphene_rect_t *crtc_layout;
|
||||
const MetaCrtcConfig *crtc_config;
|
||||
const graphene_rect_t *crtc_layout;
|
||||
|
||||
crtc = meta_output_get_assigned_crtc (output);
|
||||
if (!crtc)
|
||||
continue;
|
||||
|
||||
crtc_config = crtc->config;
|
||||
crtc_config = meta_crtc_get_config (crtc);
|
||||
g_return_if_fail (crtc_config);
|
||||
|
||||
crtc_layout = &crtc_config->layout;
|
||||
@@ -1512,7 +1580,8 @@ is_current_mode_known (MetaMonitor *monitor)
|
||||
output = meta_monitor_get_main_output (monitor);
|
||||
crtc = meta_output_get_assigned_crtc (output);
|
||||
|
||||
return meta_monitor_is_active (monitor) == (crtc && crtc->config);
|
||||
return (meta_monitor_is_active (monitor) ==
|
||||
(crtc && meta_crtc_get_config (crtc)));
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -21,35 +21,180 @@
|
||||
|
||||
#include "backends/meta-output.h"
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_ID,
|
||||
PROP_GPU,
|
||||
PROP_INFO,
|
||||
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[N_PROPS];
|
||||
|
||||
typedef struct _MetaOutputPrivate
|
||||
{
|
||||
uint64_t id;
|
||||
|
||||
MetaGpu *gpu;
|
||||
|
||||
MetaOutputInfo *info;
|
||||
|
||||
/* The CRTC driving this output, NULL if the output is not enabled */
|
||||
MetaCrtc *crtc;
|
||||
|
||||
gboolean is_primary;
|
||||
gboolean is_presentation;
|
||||
|
||||
gboolean is_underscanning;
|
||||
|
||||
int backlight;
|
||||
} MetaOutputPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaOutput, meta_output, G_TYPE_OBJECT)
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaOutput, meta_output, G_TYPE_OBJECT)
|
||||
|
||||
G_DEFINE_BOXED_TYPE (MetaOutputInfo, meta_output_info,
|
||||
meta_output_info_ref,
|
||||
meta_output_info_unref)
|
||||
|
||||
MetaOutputInfo *
|
||||
meta_output_info_new (void)
|
||||
{
|
||||
MetaOutputInfo *output_info;
|
||||
|
||||
output_info = g_new0 (MetaOutputInfo, 1);
|
||||
g_ref_count_init (&output_info->ref_count);
|
||||
|
||||
return output_info;
|
||||
}
|
||||
|
||||
MetaOutputInfo *
|
||||
meta_output_info_ref (MetaOutputInfo *output_info)
|
||||
{
|
||||
g_ref_count_inc (&output_info->ref_count);
|
||||
return output_info;
|
||||
}
|
||||
|
||||
void
|
||||
meta_output_info_unref (MetaOutputInfo *output_info)
|
||||
{
|
||||
if (g_ref_count_dec (&output_info->ref_count))
|
||||
{
|
||||
g_free (output_info->name);
|
||||
g_free (output_info->vendor);
|
||||
g_free (output_info->product);
|
||||
g_free (output_info->serial);
|
||||
g_free (output_info->modes);
|
||||
g_free (output_info->possible_crtcs);
|
||||
g_free (output_info->possible_clones);
|
||||
g_free (output_info);
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t
|
||||
meta_output_get_id (MetaOutput *output)
|
||||
{
|
||||
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
|
||||
|
||||
return priv->id;
|
||||
}
|
||||
|
||||
MetaGpu *
|
||||
meta_output_get_gpu (MetaOutput *output)
|
||||
{
|
||||
return output->gpu;
|
||||
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
|
||||
|
||||
return priv->gpu;
|
||||
}
|
||||
|
||||
const char *
|
||||
meta_output_get_name (MetaOutput *output)
|
||||
{
|
||||
return output->name;
|
||||
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
|
||||
|
||||
return priv->info->name;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_output_is_primary (MetaOutput *output)
|
||||
{
|
||||
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
|
||||
|
||||
return priv->is_primary;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_output_is_presentation (MetaOutput *output)
|
||||
{
|
||||
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
|
||||
|
||||
return priv->is_presentation;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_output_is_underscanning (MetaOutput *output)
|
||||
{
|
||||
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
|
||||
|
||||
return priv->is_underscanning;
|
||||
}
|
||||
|
||||
void
|
||||
meta_output_assign_crtc (MetaOutput *output,
|
||||
MetaCrtc *crtc)
|
||||
meta_output_set_backlight (MetaOutput *output,
|
||||
int backlight)
|
||||
{
|
||||
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
|
||||
|
||||
priv->backlight = backlight;
|
||||
}
|
||||
|
||||
int
|
||||
meta_output_get_backlight (MetaOutput *output)
|
||||
{
|
||||
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
|
||||
|
||||
return priv->backlight;
|
||||
}
|
||||
|
||||
void
|
||||
meta_output_add_possible_clone (MetaOutput *output,
|
||||
MetaOutput *possible_clone)
|
||||
{
|
||||
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
|
||||
MetaOutputInfo *output_info = priv->info;
|
||||
|
||||
output_info->n_possible_clones++;
|
||||
output_info->possible_clones = g_renew (MetaOutput *,
|
||||
output_info->possible_clones,
|
||||
output_info->n_possible_clones);
|
||||
output_info->possible_clones[output_info->n_possible_clones - 1] =
|
||||
possible_clone;
|
||||
}
|
||||
|
||||
const MetaOutputInfo *
|
||||
meta_output_get_info (MetaOutput *output)
|
||||
{
|
||||
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
|
||||
|
||||
return priv->info;
|
||||
}
|
||||
|
||||
void
|
||||
meta_output_assign_crtc (MetaOutput *output,
|
||||
MetaCrtc *crtc,
|
||||
const MetaOutputAssignment *output_assignment)
|
||||
{
|
||||
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
|
||||
|
||||
g_assert (crtc);
|
||||
|
||||
g_set_object (&priv->crtc, crtc);
|
||||
|
||||
priv->is_primary = output_assignment->is_primary;
|
||||
priv->is_presentation = output_assignment->is_presentation;
|
||||
priv->is_underscanning = output_assignment->is_underscanning;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -58,6 +203,9 @@ meta_output_unassign_crtc (MetaOutput *output)
|
||||
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
|
||||
|
||||
g_clear_object (&priv->crtc);
|
||||
|
||||
priv->is_primary = FALSE;
|
||||
priv->is_presentation = FALSE;
|
||||
}
|
||||
|
||||
MetaCrtc *
|
||||
@@ -72,9 +220,10 @@ MetaMonitorTransform
|
||||
meta_output_logical_to_crtc_transform (MetaOutput *output,
|
||||
MetaMonitorTransform transform)
|
||||
{
|
||||
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
|
||||
MetaMonitorTransform panel_orientation_transform;
|
||||
|
||||
panel_orientation_transform = output->panel_orientation_transform;
|
||||
panel_orientation_transform = priv->info->panel_orientation_transform;
|
||||
return meta_monitor_transform_transform (transform,
|
||||
panel_orientation_transform);
|
||||
}
|
||||
@@ -83,14 +232,65 @@ MetaMonitorTransform
|
||||
meta_output_crtc_to_logical_transform (MetaOutput *output,
|
||||
MetaMonitorTransform transform)
|
||||
{
|
||||
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
|
||||
MetaMonitorTransform inverted_panel_orientation_transform;
|
||||
|
||||
inverted_panel_orientation_transform =
|
||||
meta_monitor_transform_invert (output->panel_orientation_transform);
|
||||
meta_monitor_transform_invert (priv->info->panel_orientation_transform);
|
||||
return meta_monitor_transform_transform (transform,
|
||||
inverted_panel_orientation_transform);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_output_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaOutput *output = META_OUTPUT (object);
|
||||
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ID:
|
||||
priv->id = g_value_get_uint64 (value);
|
||||
break;
|
||||
case PROP_GPU:
|
||||
priv->gpu = g_value_get_object (value);
|
||||
break;
|
||||
case PROP_INFO:
|
||||
priv->info = meta_output_info_ref (g_value_get_boxed (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_output_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaOutput *output = META_OUTPUT (object);
|
||||
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ID:
|
||||
g_value_set_uint64 (value, priv->id);
|
||||
break;
|
||||
case PROP_GPU:
|
||||
g_value_set_object (value, priv->gpu);
|
||||
break;
|
||||
case PROP_INFO:
|
||||
g_value_set_boxed (value, priv->info);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_output_dispose (GObject *object)
|
||||
{
|
||||
@@ -106,17 +306,9 @@ static void
|
||||
meta_output_finalize (GObject *object)
|
||||
{
|
||||
MetaOutput *output = META_OUTPUT (object);
|
||||
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
|
||||
|
||||
g_free (output->name);
|
||||
g_free (output->vendor);
|
||||
g_free (output->product);
|
||||
g_free (output->serial);
|
||||
g_free (output->modes);
|
||||
g_free (output->possible_crtcs);
|
||||
g_free (output->possible_clones);
|
||||
|
||||
if (output->driver_notify)
|
||||
output->driver_notify (output);
|
||||
g_clear_pointer (&priv->info, meta_output_info_unref);
|
||||
|
||||
G_OBJECT_CLASS (meta_output_parent_class)->finalize (object);
|
||||
}
|
||||
@@ -124,6 +316,9 @@ meta_output_finalize (GObject *object)
|
||||
static void
|
||||
meta_output_init (MetaOutput *output)
|
||||
{
|
||||
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
|
||||
|
||||
priv->backlight = -1;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -131,6 +326,34 @@ meta_output_class_init (MetaOutputClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->set_property = meta_output_set_property;
|
||||
object_class->get_property = meta_output_get_property;
|
||||
object_class->dispose = meta_output_dispose;
|
||||
object_class->finalize = meta_output_finalize;
|
||||
|
||||
obj_props[PROP_ID] =
|
||||
g_param_spec_uint64 ("id",
|
||||
"id",
|
||||
"CRTC id",
|
||||
0, UINT64_MAX, 0,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
obj_props[PROP_GPU] =
|
||||
g_param_spec_object ("gpu",
|
||||
"gpu",
|
||||
"MetaGpu",
|
||||
META_TYPE_GPU,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
obj_props[PROP_INFO] =
|
||||
g_param_spec_boxed ("info",
|
||||
"info",
|
||||
"MetaOutputInfo",
|
||||
META_TYPE_OUTPUT_INFO,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_properties (object_class, N_PROPS, obj_props);
|
||||
}
|
||||
|
@@ -60,14 +60,10 @@ typedef enum
|
||||
META_CONNECTOR_TYPE_DSI = 16,
|
||||
} MetaConnectorType;
|
||||
|
||||
struct _MetaOutput
|
||||
typedef struct _MetaOutputInfo
|
||||
{
|
||||
GObject parent;
|
||||
grefcount ref_count;
|
||||
|
||||
MetaGpu *gpu;
|
||||
|
||||
/* The low-level ID of this output, used to apply back configuration */
|
||||
uint64_t winsys_id;
|
||||
char *name;
|
||||
char *vendor;
|
||||
char *product;
|
||||
@@ -89,35 +85,52 @@ struct _MetaOutput
|
||||
MetaOutput **possible_clones;
|
||||
unsigned int n_possible_clones;
|
||||
|
||||
int backlight;
|
||||
int backlight_min;
|
||||
int backlight_max;
|
||||
|
||||
/* Used when changing configuration */
|
||||
gboolean is_dirty;
|
||||
|
||||
gboolean is_primary;
|
||||
gboolean is_presentation;
|
||||
|
||||
gboolean is_underscanning;
|
||||
gboolean supports_underscanning;
|
||||
|
||||
gpointer driver_private;
|
||||
GDestroyNotify driver_notify;
|
||||
|
||||
/*
|
||||
* Get a new preferred mode on hotplug events, to handle dynamic guest
|
||||
* resizing.
|
||||
*/
|
||||
gboolean hotplug_mode_update;
|
||||
gint suggested_x;
|
||||
gint suggested_y;
|
||||
int suggested_x;
|
||||
int suggested_y;
|
||||
|
||||
MetaTileInfo tile_info;
|
||||
};
|
||||
} MetaOutputInfo;
|
||||
|
||||
#define META_TYPE_OUTPUT_INFO (meta_output_info_get_type ())
|
||||
META_EXPORT_TEST
|
||||
GType meta_output_info_get_type (void);
|
||||
|
||||
META_EXPORT_TEST
|
||||
MetaOutputInfo * meta_output_info_new (void);
|
||||
|
||||
META_EXPORT_TEST
|
||||
MetaOutputInfo * meta_output_info_ref (MetaOutputInfo *output_info);
|
||||
|
||||
META_EXPORT_TEST
|
||||
void meta_output_info_unref (MetaOutputInfo *output_info);
|
||||
|
||||
META_EXPORT_TEST
|
||||
void meta_output_info_parse_edid (MetaOutputInfo *output_info,
|
||||
GBytes *edid);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaOutputInfo, meta_output_info_unref)
|
||||
|
||||
#define META_TYPE_OUTPUT (meta_output_get_type ())
|
||||
META_EXPORT_TEST G_DECLARE_FINAL_TYPE (MetaOutput, meta_output, META, OUTPUT, GObject)
|
||||
META_EXPORT_TEST
|
||||
G_DECLARE_DERIVABLE_TYPE (MetaOutput, meta_output, META, OUTPUT, GObject)
|
||||
|
||||
struct _MetaOutputClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
META_EXPORT_TEST
|
||||
uint64_t meta_output_get_id (MetaOutput *output);
|
||||
|
||||
META_EXPORT_TEST
|
||||
MetaGpu * meta_output_get_gpu (MetaOutput *output);
|
||||
@@ -125,8 +138,28 @@ MetaGpu * meta_output_get_gpu (MetaOutput *output);
|
||||
const char * meta_output_get_name (MetaOutput *output);
|
||||
|
||||
META_EXPORT_TEST
|
||||
void meta_output_assign_crtc (MetaOutput *output,
|
||||
MetaCrtc *crtc);
|
||||
gboolean meta_output_is_primary (MetaOutput *output);
|
||||
|
||||
META_EXPORT_TEST
|
||||
gboolean meta_output_is_presentation (MetaOutput *output);
|
||||
|
||||
META_EXPORT_TEST
|
||||
gboolean meta_output_is_underscanning (MetaOutput *output);
|
||||
|
||||
void meta_output_set_backlight (MetaOutput *output,
|
||||
int backlight);
|
||||
|
||||
int meta_output_get_backlight (MetaOutput *output);
|
||||
|
||||
void meta_output_add_possible_clone (MetaOutput *output,
|
||||
MetaOutput *possible_clone);
|
||||
|
||||
const MetaOutputInfo * meta_output_get_info (MetaOutput *output);
|
||||
|
||||
META_EXPORT_TEST
|
||||
void meta_output_assign_crtc (MetaOutput *output,
|
||||
MetaCrtc *crtc,
|
||||
const MetaOutputAssignment *output_assignment);
|
||||
|
||||
META_EXPORT_TEST
|
||||
void meta_output_unassign_crtc (MetaOutput *output);
|
||||
|
@@ -194,23 +194,8 @@ meta_renderer_is_hardware_accelerated (MetaRenderer *renderer)
|
||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||
CoglContext *cogl_context =
|
||||
clutter_backend_get_cogl_context (clutter_backend);
|
||||
CoglGpuInfo *info = &cogl_context->gpu;
|
||||
|
||||
switch (info->architecture)
|
||||
{
|
||||
case COGL_GPU_INFO_ARCHITECTURE_UNKNOWN:
|
||||
case COGL_GPU_INFO_ARCHITECTURE_SANDYBRIDGE:
|
||||
case COGL_GPU_INFO_ARCHITECTURE_SGX:
|
||||
case COGL_GPU_INFO_ARCHITECTURE_MALI:
|
||||
return TRUE;
|
||||
case COGL_GPU_INFO_ARCHITECTURE_LLVMPIPE:
|
||||
case COGL_GPU_INFO_ARCHITECTURE_SOFTPIPE:
|
||||
case COGL_GPU_INFO_ARCHITECTURE_SWRAST:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_assert_not_reached ();
|
||||
return FALSE;
|
||||
return cogl_context_is_hardware_accelerated (cogl_context);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -42,6 +42,7 @@
|
||||
|
||||
#include "backends/meta-cursor-tracker-private.h"
|
||||
#include "backends/meta-idle-monitor-private.h"
|
||||
#include "backends/meta-keymap-utils.h"
|
||||
#include "backends/meta-logical-monitor.h"
|
||||
#include "backends/meta-monitor-manager-private.h"
|
||||
#include "backends/meta-pointer-constraint.h"
|
||||
@@ -340,7 +341,7 @@ meta_backend_native_create_clutter_backend (MetaBackend *backend)
|
||||
static void
|
||||
meta_backend_native_post_init (MetaBackend *backend)
|
||||
{
|
||||
ClutterBackend *clutter_backend = clutter_get_default_backend ();
|
||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||
ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend);
|
||||
MetaSettings *settings = meta_backend_get_settings (backend);
|
||||
|
||||
@@ -425,6 +426,7 @@ meta_backend_native_set_keymap (MetaBackend *backend,
|
||||
const char *variants,
|
||||
const char *options)
|
||||
{
|
||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||
struct xkb_rule_names names;
|
||||
struct xkb_keymap *keymap;
|
||||
struct xkb_context *context;
|
||||
@@ -436,11 +438,11 @@ meta_backend_native_set_keymap (MetaBackend *backend,
|
||||
names.variant = variants;
|
||||
names.options = options;
|
||||
|
||||
context = xkb_context_new (XKB_CONTEXT_NO_FLAGS);
|
||||
context = meta_create_xkb_context ();
|
||||
keymap = xkb_keymap_new_from_names (context, &names, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
xkb_context_unref (context);
|
||||
|
||||
seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
||||
seat = clutter_backend_get_default_seat (clutter_backend);
|
||||
meta_seat_native_set_keyboard_map (META_SEAT_NATIVE (seat), keymap);
|
||||
|
||||
meta_backend_notify_keymap_changed (backend);
|
||||
@@ -451,18 +453,20 @@ meta_backend_native_set_keymap (MetaBackend *backend,
|
||||
static struct xkb_keymap *
|
||||
meta_backend_native_get_keymap (MetaBackend *backend)
|
||||
{
|
||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||
ClutterSeat *seat;
|
||||
|
||||
seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
||||
seat = clutter_backend_get_default_seat (clutter_backend);
|
||||
return meta_seat_native_get_keyboard_map (META_SEAT_NATIVE (seat));
|
||||
}
|
||||
|
||||
static xkb_layout_index_t
|
||||
meta_backend_native_get_keymap_layout_group (MetaBackend *backend)
|
||||
{
|
||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||
ClutterSeat *seat;
|
||||
|
||||
seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
||||
seat = clutter_backend_get_default_seat (clutter_backend);
|
||||
return meta_seat_native_get_keyboard_layout_index (META_SEAT_NATIVE (seat));
|
||||
}
|
||||
|
||||
@@ -470,6 +474,7 @@ static void
|
||||
meta_backend_native_lock_layout_group (MetaBackend *backend,
|
||||
guint idx)
|
||||
{
|
||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||
xkb_layout_index_t old_idx;
|
||||
ClutterSeat *seat;
|
||||
|
||||
@@ -477,7 +482,7 @@ meta_backend_native_lock_layout_group (MetaBackend *backend,
|
||||
if (old_idx == idx)
|
||||
return;
|
||||
|
||||
seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
||||
seat = clutter_backend_get_default_seat (clutter_backend);
|
||||
meta_seat_native_set_keyboard_layout_index (META_SEAT_NATIVE (seat), idx);
|
||||
meta_backend_notify_keymap_layout_group_changed (backend, idx);
|
||||
}
|
||||
@@ -486,9 +491,10 @@ static void
|
||||
meta_backend_native_set_numlock (MetaBackend *backend,
|
||||
gboolean numlock_state)
|
||||
{
|
||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||
ClutterSeat *seat;
|
||||
|
||||
seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
||||
seat = clutter_backend_get_default_seat (clutter_backend);
|
||||
meta_seat_native_set_keyboard_numlock (META_SEAT_NATIVE (seat),
|
||||
numlock_state);
|
||||
}
|
||||
@@ -780,7 +786,7 @@ meta_backend_native_pause (MetaBackendNative *native)
|
||||
meta_backend_get_monitor_manager (backend);
|
||||
MetaMonitorManagerKms *monitor_manager_kms =
|
||||
META_MONITOR_MANAGER_KMS (monitor_manager);
|
||||
ClutterBackend *clutter_backend = clutter_get_default_backend ();
|
||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||
MetaSeatNative *seat =
|
||||
META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend));
|
||||
|
||||
@@ -805,7 +811,7 @@ void meta_backend_native_resume (MetaBackendNative *native)
|
||||
META_MONITOR_MANAGER_KMS (monitor_manager);
|
||||
MetaInputSettings *input_settings;
|
||||
MetaIdleMonitor *idle_monitor;
|
||||
ClutterBackend *clutter_backend = clutter_get_default_backend ();
|
||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||
MetaSeatNative *seat =
|
||||
META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend));
|
||||
|
||||
|
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "backends/meta-backend-private.h"
|
||||
#include "backends/meta-logical-monitor.h"
|
||||
#include "backends/native/meta-crtc-mode-kms.h"
|
||||
#include "backends/native/meta-gpu-kms.h"
|
||||
#include "backends/native/meta-output-kms.h"
|
||||
#include "backends/native/meta-kms-device.h"
|
||||
@@ -34,21 +35,38 @@
|
||||
|
||||
#define ALL_TRANSFORMS_MASK ((1 << META_MONITOR_N_TRANSFORMS) - 1)
|
||||
|
||||
typedef struct _MetaCrtcKms
|
||||
struct _MetaCrtcKms
|
||||
{
|
||||
MetaCrtc parent;
|
||||
|
||||
MetaKmsCrtc *kms_crtc;
|
||||
|
||||
MetaKmsPlane *primary_plane;
|
||||
} MetaCrtcKms;
|
||||
|
||||
gpointer cursor_renderer_private;
|
||||
};
|
||||
|
||||
static GQuark kms_crtc_crtc_kms_quark;
|
||||
|
||||
G_DEFINE_TYPE (MetaCrtcKms, meta_crtc_kms, META_TYPE_CRTC)
|
||||
|
||||
gpointer
|
||||
meta_crtc_kms_get_cursor_renderer_private (MetaCrtcKms *crtc_kms)
|
||||
{
|
||||
return crtc_kms->cursor_renderer_private;
|
||||
}
|
||||
|
||||
void
|
||||
meta_crtc_kms_set_cursor_renderer_private (MetaCrtcKms *crtc_kms,
|
||||
gpointer cursor_renderer_private)
|
||||
{
|
||||
crtc_kms->cursor_renderer_private = cursor_renderer_private;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_crtc_kms_is_transform_handled (MetaCrtc *crtc,
|
||||
meta_crtc_kms_is_transform_handled (MetaCrtcKms *crtc_kms,
|
||||
MetaMonitorTransform transform)
|
||||
{
|
||||
MetaCrtcKms *crtc_kms = crtc->driver_private;
|
||||
|
||||
if (!crtc_kms->primary_plane)
|
||||
return FALSE;
|
||||
|
||||
@@ -57,16 +75,19 @@ meta_crtc_kms_is_transform_handled (MetaCrtc *crtc,
|
||||
}
|
||||
|
||||
void
|
||||
meta_crtc_kms_apply_transform (MetaCrtc *crtc,
|
||||
meta_crtc_kms_apply_transform (MetaCrtcKms *crtc_kms,
|
||||
MetaKmsPlaneAssignment *kms_plane_assignment)
|
||||
{
|
||||
MetaCrtcKms *crtc_kms = crtc->driver_private;
|
||||
MetaCrtc *crtc = META_CRTC (crtc_kms);
|
||||
const MetaCrtcConfig *crtc_config;
|
||||
MetaMonitorTransform hw_transform;
|
||||
|
||||
hw_transform = crtc->config->transform;
|
||||
if (!meta_crtc_kms_is_transform_handled (crtc, hw_transform))
|
||||
crtc_config = meta_crtc_get_config (crtc);
|
||||
|
||||
hw_transform = crtc_config->transform;
|
||||
if (!meta_crtc_kms_is_transform_handled (crtc_kms, hw_transform))
|
||||
hw_transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
if (!meta_crtc_kms_is_transform_handled (crtc, hw_transform))
|
||||
if (!meta_crtc_kms_is_transform_handled (crtc_kms, hw_transform))
|
||||
return;
|
||||
|
||||
meta_kms_plane_update_set_rotation (crtc_kms->primary_plane,
|
||||
@@ -75,11 +96,13 @@ meta_crtc_kms_apply_transform (MetaCrtc *crtc,
|
||||
}
|
||||
|
||||
void
|
||||
meta_crtc_kms_assign_primary_plane (MetaCrtc *crtc,
|
||||
meta_crtc_kms_assign_primary_plane (MetaCrtcKms *crtc_kms,
|
||||
uint32_t fb_id,
|
||||
MetaKmsUpdate *kms_update)
|
||||
{
|
||||
MetaCrtcConfig *crtc_config;
|
||||
MetaCrtc *crtc = META_CRTC (crtc_kms);
|
||||
const MetaCrtcConfig *crtc_config;
|
||||
const MetaCrtcModeInfo *crtc_mode_info;
|
||||
MetaFixed16Rectangle src_rect;
|
||||
MetaFixed16Rectangle dst_rect;
|
||||
MetaKmsAssignPlaneFlag flags;
|
||||
@@ -88,25 +111,25 @@ meta_crtc_kms_assign_primary_plane (MetaCrtc *crtc,
|
||||
MetaKmsPlane *primary_kms_plane;
|
||||
MetaKmsPlaneAssignment *plane_assignment;
|
||||
|
||||
crtc_config = crtc->config;
|
||||
|
||||
crtc_config = meta_crtc_get_config (crtc);
|
||||
crtc_mode_info = meta_crtc_mode_get_info (crtc_config->mode);
|
||||
|
||||
src_rect = (MetaFixed16Rectangle) {
|
||||
.x = meta_fixed_16_from_int (0),
|
||||
.y = meta_fixed_16_from_int (0),
|
||||
.width = meta_fixed_16_from_int (crtc_config->mode->width),
|
||||
.height = meta_fixed_16_from_int (crtc_config->mode->height),
|
||||
.width = meta_fixed_16_from_int (crtc_mode_info->width),
|
||||
.height = meta_fixed_16_from_int (crtc_mode_info->height),
|
||||
};
|
||||
dst_rect = (MetaFixed16Rectangle) {
|
||||
.x = meta_fixed_16_from_int (0),
|
||||
.y = meta_fixed_16_from_int (0),
|
||||
.width = meta_fixed_16_from_int (crtc_config->mode->width),
|
||||
.height = meta_fixed_16_from_int (crtc_config->mode->height),
|
||||
.width = meta_fixed_16_from_int (crtc_mode_info->width),
|
||||
.height = meta_fixed_16_from_int (crtc_mode_info->height),
|
||||
};
|
||||
|
||||
flags = META_KMS_ASSIGN_PLANE_FLAG_NONE;
|
||||
|
||||
kms_crtc = meta_crtc_kms_get_kms_crtc (crtc);
|
||||
kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
|
||||
kms_device = meta_kms_crtc_get_device (kms_crtc);
|
||||
primary_kms_plane = meta_kms_device_get_primary_plane_for (kms_device,
|
||||
kms_crtc);
|
||||
@@ -117,7 +140,7 @@ meta_crtc_kms_assign_primary_plane (MetaCrtc *crtc,
|
||||
src_rect,
|
||||
dst_rect,
|
||||
flags);
|
||||
meta_crtc_kms_apply_transform (crtc, plane_assignment);
|
||||
meta_crtc_kms_apply_transform (crtc_kms, plane_assignment);
|
||||
}
|
||||
|
||||
static GList *
|
||||
@@ -136,7 +159,7 @@ generate_crtc_connector_list (MetaGpu *gpu,
|
||||
if (assigned_crtc == crtc)
|
||||
{
|
||||
MetaKmsConnector *kms_connector =
|
||||
meta_output_kms_get_kms_connector (output);
|
||||
meta_output_kms_get_kms_connector (META_OUTPUT_KMS (output));
|
||||
|
||||
connectors = g_list_prepend (connectors, kms_connector);
|
||||
}
|
||||
@@ -146,58 +169,61 @@ generate_crtc_connector_list (MetaGpu *gpu,
|
||||
}
|
||||
|
||||
void
|
||||
meta_crtc_kms_set_mode (MetaCrtc *crtc,
|
||||
meta_crtc_kms_set_mode (MetaCrtcKms *crtc_kms,
|
||||
MetaKmsUpdate *kms_update)
|
||||
{
|
||||
MetaCrtcConfig *crtc_config = crtc->config;
|
||||
MetaCrtc *crtc = META_CRTC (crtc_kms);
|
||||
MetaGpu *gpu = meta_crtc_get_gpu (crtc);
|
||||
GList *connectors;
|
||||
drmModeModeInfo *mode;
|
||||
const drmModeModeInfo *mode;
|
||||
|
||||
connectors = generate_crtc_connector_list (gpu, crtc);
|
||||
|
||||
if (connectors)
|
||||
{
|
||||
mode = crtc_config->mode->driver_private;
|
||||
const MetaCrtcConfig *crtc_config = meta_crtc_get_config (crtc);
|
||||
MetaCrtcModeKms *crtc_mode_kms = META_CRTC_MODE_KMS (crtc_config->mode);
|
||||
|
||||
g_debug ("Setting CRTC (%ld) mode to %s", crtc->crtc_id, mode->name);
|
||||
mode = meta_crtc_mode_kms_get_drm_mode (crtc_mode_kms);
|
||||
|
||||
g_debug ("Setting CRTC (%ld) mode to %s",
|
||||
meta_crtc_get_id (crtc), mode->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
mode = NULL;
|
||||
|
||||
g_debug ("Unsetting CRTC (%ld) mode", crtc->crtc_id);
|
||||
g_debug ("Unsetting CRTC (%ld) mode",
|
||||
meta_crtc_get_id (crtc));
|
||||
}
|
||||
|
||||
meta_kms_update_mode_set (kms_update,
|
||||
meta_crtc_kms_get_kms_crtc (crtc),
|
||||
meta_crtc_kms_get_kms_crtc (crtc_kms),
|
||||
g_steal_pointer (&connectors),
|
||||
mode);
|
||||
}
|
||||
|
||||
void
|
||||
meta_crtc_kms_page_flip (MetaCrtc *crtc,
|
||||
meta_crtc_kms_page_flip (MetaCrtcKms *crtc_kms,
|
||||
const MetaKmsPageFlipFeedback *page_flip_feedback,
|
||||
gpointer user_data,
|
||||
MetaKmsUpdate *kms_update)
|
||||
{
|
||||
meta_kms_update_page_flip (kms_update,
|
||||
meta_crtc_kms_get_kms_crtc (crtc),
|
||||
meta_crtc_kms_get_kms_crtc (crtc_kms),
|
||||
page_flip_feedback,
|
||||
user_data);
|
||||
}
|
||||
|
||||
MetaKmsCrtc *
|
||||
meta_crtc_kms_get_kms_crtc (MetaCrtc *crtc)
|
||||
meta_crtc_kms_get_kms_crtc (MetaCrtcKms *crtc_kms)
|
||||
{
|
||||
MetaCrtcKms *crtc_kms = crtc->driver_private;
|
||||
|
||||
return crtc_kms->kms_crtc;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_crtc_kms_get_modifiers:
|
||||
* @crtc: a #MetaCrtc object that has to be a #MetaCrtcKms
|
||||
* @crtc_kms: a #MetaCrtc object that has to be a #MetaCrtcKms
|
||||
* @format: a DRM pixel format
|
||||
*
|
||||
* Returns a pointer to a #GArray containing all the supported
|
||||
@@ -210,93 +236,85 @@ meta_crtc_kms_get_kms_crtc (MetaCrtc *crtc)
|
||||
* supported.
|
||||
*/
|
||||
GArray *
|
||||
meta_crtc_kms_get_modifiers (MetaCrtc *crtc,
|
||||
uint32_t format)
|
||||
meta_crtc_kms_get_modifiers (MetaCrtcKms *crtc_kms,
|
||||
uint32_t format)
|
||||
{
|
||||
MetaCrtcKms *crtc_kms = crtc->driver_private;
|
||||
|
||||
return meta_kms_plane_get_modifiers_for_format (crtc_kms->primary_plane,
|
||||
format);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_crtc_kms_copy_drm_format_list:
|
||||
* @crtc: a #MetaCrtc object that has to be a #MetaCrtcKms
|
||||
* @crtc_kms: a #MetaCrtc object that has to be a #MetaCrtcKms
|
||||
*
|
||||
* Returns a new #GArray that the caller must destroy. The array
|
||||
* contains all the DRM pixel formats the CRTC supports on
|
||||
* its primary plane. The array element type is uint32_t.
|
||||
*/
|
||||
GArray *
|
||||
meta_crtc_kms_copy_drm_format_list (MetaCrtc *crtc)
|
||||
meta_crtc_kms_copy_drm_format_list (MetaCrtcKms *crtc_kms)
|
||||
{
|
||||
MetaCrtcKms *crtc_kms = crtc->driver_private;
|
||||
|
||||
return meta_kms_plane_copy_drm_format_list (crtc_kms->primary_plane);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_crtc_kms_supports_format:
|
||||
* @crtc: a #MetaCrtc object that has to be a #MetaCrtcKms
|
||||
* @crtc_kms: a #MetaCrtcKms
|
||||
* @drm_format: a DRM pixel format
|
||||
*
|
||||
* Returns true if the CRTC supports the format on its primary plane.
|
||||
*/
|
||||
gboolean
|
||||
meta_crtc_kms_supports_format (MetaCrtc *crtc,
|
||||
uint32_t drm_format)
|
||||
meta_crtc_kms_supports_format (MetaCrtcKms *crtc_kms,
|
||||
uint32_t drm_format)
|
||||
{
|
||||
MetaCrtcKms *crtc_kms = crtc->driver_private;
|
||||
|
||||
return meta_kms_plane_is_format_supported (crtc_kms->primary_plane,
|
||||
drm_format);
|
||||
}
|
||||
|
||||
MetaCrtc *
|
||||
MetaCrtcKms *
|
||||
meta_crtc_kms_from_kms_crtc (MetaKmsCrtc *kms_crtc)
|
||||
{
|
||||
return g_object_get_qdata (G_OBJECT (kms_crtc), kms_crtc_crtc_kms_quark);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_crtc_destroy_notify (MetaCrtc *crtc)
|
||||
{
|
||||
g_free (crtc->driver_private);
|
||||
}
|
||||
|
||||
MetaCrtc *
|
||||
meta_create_kms_crtc (MetaGpuKms *gpu_kms,
|
||||
MetaKmsCrtc *kms_crtc)
|
||||
MetaCrtcKms *
|
||||
meta_crtc_kms_new (MetaGpuKms *gpu_kms,
|
||||
MetaKmsCrtc *kms_crtc)
|
||||
{
|
||||
MetaGpu *gpu = META_GPU (gpu_kms);
|
||||
MetaKmsDevice *kms_device;
|
||||
MetaCrtc *crtc;
|
||||
MetaCrtcKms *crtc_kms;
|
||||
MetaKmsPlane *primary_plane;
|
||||
|
||||
kms_device = meta_gpu_kms_get_kms_device (gpu_kms);
|
||||
primary_plane = meta_kms_device_get_primary_plane_for (kms_device,
|
||||
kms_crtc);
|
||||
crtc = g_object_new (META_TYPE_CRTC, NULL);
|
||||
crtc->gpu = gpu;
|
||||
crtc->crtc_id = meta_kms_crtc_get_id (kms_crtc);
|
||||
crtc->is_dirty = FALSE;
|
||||
crtc->all_transforms = ALL_TRANSFORMS_MASK;
|
||||
crtc_kms = g_object_new (META_TYPE_CRTC_KMS,
|
||||
"id", meta_kms_crtc_get_id (kms_crtc),
|
||||
"gpu", gpu,
|
||||
NULL);
|
||||
|
||||
crtc_kms = g_new0 (MetaCrtcKms, 1);
|
||||
crtc_kms->kms_crtc = kms_crtc;
|
||||
crtc_kms->primary_plane = primary_plane;
|
||||
|
||||
crtc->driver_private = crtc_kms;
|
||||
crtc->driver_notify = (GDestroyNotify) meta_crtc_destroy_notify;
|
||||
|
||||
if (!kms_crtc_crtc_kms_quark)
|
||||
{
|
||||
kms_crtc_crtc_kms_quark =
|
||||
g_quark_from_static_string ("meta-kms-crtc-crtc-kms-quark");
|
||||
}
|
||||
|
||||
g_object_set_qdata (G_OBJECT (kms_crtc), kms_crtc_crtc_kms_quark, crtc);
|
||||
g_object_set_qdata (G_OBJECT (kms_crtc), kms_crtc_crtc_kms_quark, crtc_kms);
|
||||
|
||||
return crtc;
|
||||
return crtc_kms;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_crtc_kms_init (MetaCrtcKms *crtc_kms)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_crtc_kms_class_init (MetaCrtcKmsClass *klass)
|
||||
{
|
||||
}
|
||||
|
@@ -31,42 +31,52 @@
|
||||
#include "backends/native/meta-gpu-kms.h"
|
||||
#include "backends/native/meta-kms-crtc.h"
|
||||
|
||||
gboolean meta_crtc_kms_is_transform_handled (MetaCrtc *crtc,
|
||||
#define META_TYPE_CRTC_KMS (meta_crtc_kms_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaCrtcKms, meta_crtc_kms,
|
||||
META, CRTC_KMS,
|
||||
MetaCrtc)
|
||||
|
||||
gpointer meta_crtc_kms_get_cursor_renderer_private (MetaCrtcKms *crtc_kms);
|
||||
|
||||
void meta_crtc_kms_set_cursor_renderer_private (MetaCrtcKms *crtc_kms,
|
||||
gpointer cursor_renderer_private);
|
||||
|
||||
gboolean meta_crtc_kms_is_transform_handled (MetaCrtcKms *crtc_kms,
|
||||
MetaMonitorTransform transform);
|
||||
|
||||
void meta_crtc_kms_apply_transform (MetaCrtc *crtc,
|
||||
void meta_crtc_kms_apply_transform (MetaCrtcKms *crtc_kms,
|
||||
MetaKmsPlaneAssignment *kms_plane_assignment);
|
||||
|
||||
void meta_crtc_kms_assign_primary_plane (MetaCrtc *crtc,
|
||||
void meta_crtc_kms_assign_primary_plane (MetaCrtcKms *crtc_kms,
|
||||
uint32_t fb_id,
|
||||
MetaKmsUpdate *kms_update);
|
||||
|
||||
void meta_crtc_kms_set_mode (MetaCrtc *crtc,
|
||||
void meta_crtc_kms_set_mode (MetaCrtcKms *crtc_kms,
|
||||
MetaKmsUpdate *kms_update);
|
||||
|
||||
void meta_crtc_kms_page_flip (MetaCrtc *crtc,
|
||||
void meta_crtc_kms_page_flip (MetaCrtcKms *crtc_kms,
|
||||
const MetaKmsPageFlipFeedback *page_flip_feedback,
|
||||
gpointer user_data,
|
||||
MetaKmsUpdate *kms_update);
|
||||
|
||||
void meta_crtc_kms_set_is_underscanning (MetaCrtc *crtc,
|
||||
gboolean is_underscanning);
|
||||
void meta_crtc_kms_set_is_underscanning (MetaCrtcKms *crtc_kms,
|
||||
gboolean is_underscanning);
|
||||
|
||||
MetaKmsCrtc * meta_crtc_kms_get_kms_crtc (MetaCrtc *crtc);
|
||||
MetaKmsCrtc * meta_crtc_kms_get_kms_crtc (MetaCrtcKms *crtc_kms);
|
||||
|
||||
GArray * meta_crtc_kms_get_modifiers (MetaCrtc *crtc,
|
||||
uint32_t format);
|
||||
GArray * meta_crtc_kms_get_modifiers (MetaCrtcKms *crtc_kms,
|
||||
uint32_t format);
|
||||
|
||||
GArray *
|
||||
meta_crtc_kms_copy_drm_format_list (MetaCrtc *crtc);
|
||||
meta_crtc_kms_copy_drm_format_list (MetaCrtcKms *crtc_kms);
|
||||
|
||||
gboolean
|
||||
meta_crtc_kms_supports_format (MetaCrtc *crtc,
|
||||
uint32_t drm_format);
|
||||
meta_crtc_kms_supports_format (MetaCrtcKms *crtc_kms,
|
||||
uint32_t drm_format);
|
||||
|
||||
MetaCrtc * meta_crtc_kms_from_kms_crtc (MetaKmsCrtc *kms_crtc);
|
||||
MetaCrtcKms * meta_crtc_kms_from_kms_crtc (MetaKmsCrtc *kms_crtc);
|
||||
|
||||
MetaCrtc * meta_create_kms_crtc (MetaGpuKms *gpu_kms,
|
||||
MetaCrtcKms * meta_crtc_kms_new (MetaGpuKms *gpu_kms,
|
||||
MetaKmsCrtc *kms_crtc);
|
||||
|
||||
#endif /* META_CRTC_KMS_H */
|
||||
|
90
src/backends/native/meta-crtc-mode-kms.c
Normal file
90
src/backends/native/meta-crtc-mode-kms.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2020 Red Hat
|
||||
*
|
||||
* 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-crtc-mode-kms.h"
|
||||
|
||||
#include "backends/native/meta-kms-utils.h"
|
||||
|
||||
struct _MetaCrtcModeKms
|
||||
{
|
||||
MetaCrtcMode parent;
|
||||
|
||||
drmModeModeInfo *drm_mode;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaCrtcModeKms, meta_crtc_mode_kms,
|
||||
META_TYPE_CRTC_MODE)
|
||||
|
||||
const drmModeModeInfo *
|
||||
meta_crtc_mode_kms_get_drm_mode (MetaCrtcModeKms *mode_kms)
|
||||
{
|
||||
return mode_kms->drm_mode;
|
||||
}
|
||||
|
||||
MetaCrtcModeKms *
|
||||
meta_crtc_mode_kms_new (const drmModeModeInfo *drm_mode,
|
||||
uint64_t id)
|
||||
{
|
||||
g_autoptr (MetaCrtcModeInfo) crtc_mode_info = NULL;
|
||||
g_autofree char *crtc_mode_name = NULL;
|
||||
MetaCrtcModeKms *mode_kms;
|
||||
|
||||
crtc_mode_info = meta_crtc_mode_info_new ();
|
||||
crtc_mode_info->width = drm_mode->hdisplay;
|
||||
crtc_mode_info->height = drm_mode->vdisplay;
|
||||
crtc_mode_info->flags = drm_mode->flags;
|
||||
crtc_mode_info->refresh_rate =
|
||||
meta_calculate_drm_mode_refresh_rate (drm_mode);
|
||||
|
||||
crtc_mode_name = g_strndup (drm_mode->name, DRM_DISPLAY_MODE_LEN);
|
||||
mode_kms = g_object_new (META_TYPE_CRTC_MODE_KMS,
|
||||
"id", id,
|
||||
"name", crtc_mode_name,
|
||||
"info", crtc_mode_info,
|
||||
NULL);
|
||||
|
||||
mode_kms->drm_mode = g_slice_dup (drmModeModeInfo, drm_mode);
|
||||
|
||||
return mode_kms;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_crtc_mode_kms_finalize (GObject *object)
|
||||
{
|
||||
MetaCrtcModeKms *mode_kms = META_CRTC_MODE_KMS (object);
|
||||
|
||||
g_slice_free (drmModeModeInfo, mode_kms->drm_mode);
|
||||
|
||||
G_OBJECT_CLASS (meta_crtc_mode_kms_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_crtc_mode_kms_init (MetaCrtcModeKms *mode_kms)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_crtc_mode_kms_class_init (MetaCrtcModeKmsClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = meta_crtc_mode_kms_finalize;
|
||||
}
|
38
src/backends/native/meta-crtc-mode-kms.h
Normal file
38
src/backends/native/meta-crtc-mode-kms.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2020 Red Hat
|
||||
*
|
||||
* 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_CRTC_MODE_KMS_H
|
||||
#define META_CRTC_MODE_KMS_H
|
||||
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
|
||||
#include "backends/meta-crtc-mode.h"
|
||||
|
||||
#define META_TYPE_CRTC_MODE_KMS (meta_crtc_mode_kms_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaCrtcModeKms, meta_crtc_mode_kms,
|
||||
META, CRTC_MODE_KMS,
|
||||
MetaCrtcMode)
|
||||
|
||||
const drmModeModeInfo * meta_crtc_mode_kms_get_drm_mode (MetaCrtcModeKms *crtc_mode_kms);
|
||||
|
||||
MetaCrtcModeKms * meta_crtc_mode_kms_new (const drmModeModeInfo *drm_mode,
|
||||
uint64_t id);
|
||||
|
||||
#endif /* META_CRTC_MODE_KMS_H */
|
@@ -251,13 +251,14 @@ calculate_crtc_cursor_hotspot (MetaCursorSprite *cursor_sprite,
|
||||
static void
|
||||
set_crtc_cursor (MetaCursorRendererNative *native,
|
||||
MetaKmsUpdate *kms_update,
|
||||
MetaCrtc *crtc,
|
||||
MetaCrtcKms *crtc_kms,
|
||||
int x,
|
||||
int y,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorRendererNativePrivate *priv =
|
||||
meta_cursor_renderer_native_get_instance_private (native);
|
||||
MetaCrtc *crtc = META_CRTC (crtc_kms);
|
||||
MetaCursorNativePrivate *cursor_priv = get_cursor_priv (cursor_sprite);
|
||||
MetaGpuKms *gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc));
|
||||
MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data =
|
||||
@@ -272,6 +273,7 @@ set_crtc_cursor (MetaCursorRendererNative *native,
|
||||
int cursor_width, cursor_height;
|
||||
MetaFixed16Rectangle src_rect;
|
||||
MetaFixed16Rectangle dst_rect;
|
||||
struct gbm_bo *crtc_bo;
|
||||
MetaKmsAssignPlaneFlag flags;
|
||||
int cursor_hotspot_x;
|
||||
int cursor_hotspot_y;
|
||||
@@ -282,7 +284,7 @@ set_crtc_cursor (MetaCursorRendererNative *native,
|
||||
else
|
||||
bo = get_active_cursor_sprite_gbm_bo (cursor_gpu_state);
|
||||
|
||||
kms_crtc = meta_crtc_kms_get_kms_crtc (crtc);
|
||||
kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
|
||||
kms_device = meta_kms_crtc_get_device (kms_crtc);
|
||||
cursor_plane = meta_kms_device_get_cursor_plane_for (kms_device, kms_crtc);
|
||||
g_return_if_fail (cursor_plane);
|
||||
@@ -305,7 +307,8 @@ set_crtc_cursor (MetaCursorRendererNative *native,
|
||||
};
|
||||
|
||||
flags = META_KMS_ASSIGN_PLANE_FLAG_NONE;
|
||||
if (!priv->hw_state_invalidated && bo == crtc->cursor_renderer_private)
|
||||
crtc_bo = meta_crtc_kms_get_cursor_renderer_private (crtc_kms);
|
||||
if (!priv->hw_state_invalidated && bo == crtc_bo)
|
||||
flags |= META_KMS_ASSIGN_PLANE_FLAG_FB_UNCHANGED;
|
||||
|
||||
plane_assignment = meta_kms_update_assign_plane (kms_update,
|
||||
@@ -323,7 +326,7 @@ set_crtc_cursor (MetaCursorRendererNative *native,
|
||||
cursor_hotspot_x,
|
||||
cursor_hotspot_y);
|
||||
|
||||
crtc->cursor_renderer_private = bo;
|
||||
meta_crtc_kms_set_cursor_renderer_private (crtc_kms, bo);
|
||||
|
||||
if (cursor_gpu_state->pending_bo_state == META_CURSOR_GBM_BO_STATE_SET)
|
||||
{
|
||||
@@ -336,25 +339,27 @@ set_crtc_cursor (MetaCursorRendererNative *native,
|
||||
static void
|
||||
unset_crtc_cursor (MetaCursorRendererNative *native,
|
||||
MetaKmsUpdate *kms_update,
|
||||
MetaCrtc *crtc)
|
||||
MetaCrtcKms *crtc_kms)
|
||||
{
|
||||
MetaCursorRendererNativePrivate *priv =
|
||||
meta_cursor_renderer_native_get_instance_private (native);
|
||||
MetaKmsCrtc *kms_crtc;
|
||||
MetaKmsDevice *kms_device;
|
||||
MetaKmsPlane *cursor_plane;
|
||||
struct gbm_bo *crtc_bo;
|
||||
|
||||
if (!priv->hw_state_invalidated && !crtc->cursor_renderer_private)
|
||||
crtc_bo = meta_crtc_kms_get_cursor_renderer_private (crtc_kms);
|
||||
if (!priv->hw_state_invalidated && !crtc_bo)
|
||||
return;
|
||||
|
||||
kms_crtc = meta_crtc_kms_get_kms_crtc (crtc);
|
||||
kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
|
||||
kms_device = meta_kms_crtc_get_device (kms_crtc);
|
||||
cursor_plane = meta_kms_device_get_cursor_plane_for (kms_device, kms_crtc);
|
||||
|
||||
if (cursor_plane)
|
||||
meta_kms_update_unassign_plane (kms_update, kms_crtc, cursor_plane);
|
||||
|
||||
crtc->cursor_renderer_private = NULL;
|
||||
meta_crtc_kms_set_cursor_renderer_private (crtc_kms, NULL);
|
||||
}
|
||||
|
||||
static float
|
||||
@@ -397,6 +402,7 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
|
||||
meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
|
||||
MetaCrtc *crtc;
|
||||
MetaMonitorTransform transform;
|
||||
const MetaCrtcModeInfo *crtc_mode_info;
|
||||
graphene_rect_t scaled_crtc_rect;
|
||||
float scale;
|
||||
int crtc_x, crtc_y;
|
||||
@@ -415,15 +421,17 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
|
||||
transform,
|
||||
&crtc_x, &crtc_y);
|
||||
|
||||
crtc_mode_info = meta_crtc_mode_get_info (monitor_crtc_mode->crtc_mode);
|
||||
|
||||
if (meta_monitor_transform_is_rotated (transform))
|
||||
{
|
||||
crtc_width = monitor_crtc_mode->crtc_mode->height;
|
||||
crtc_height = monitor_crtc_mode->crtc_mode->width;
|
||||
crtc_width = crtc_mode_info->height;
|
||||
crtc_height = crtc_mode_info->width;
|
||||
}
|
||||
else
|
||||
{
|
||||
crtc_width = monitor_crtc_mode->crtc_mode->width;
|
||||
crtc_height = monitor_crtc_mode->crtc_mode->height;
|
||||
crtc_width = crtc_mode_info->width;
|
||||
crtc_height = crtc_mode_info->height;
|
||||
}
|
||||
|
||||
scaled_crtc_rect = (graphene_rect_t) {
|
||||
@@ -474,13 +482,13 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
|
||||
inverted_transform = meta_monitor_transform_invert (transform);
|
||||
meta_rectangle_transform (&cursor_rect,
|
||||
inverted_transform,
|
||||
monitor_crtc_mode->crtc_mode->width,
|
||||
monitor_crtc_mode->crtc_mode->height,
|
||||
crtc_mode_info->width,
|
||||
crtc_mode_info->height,
|
||||
&cursor_rect);
|
||||
|
||||
set_crtc_cursor (data->in_cursor_renderer_native,
|
||||
data->in_kms_update,
|
||||
crtc,
|
||||
META_CRTC_KMS (crtc),
|
||||
cursor_rect.x,
|
||||
cursor_rect.y,
|
||||
data->in_cursor_sprite);
|
||||
@@ -491,7 +499,7 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
|
||||
{
|
||||
unset_crtc_cursor (data->in_cursor_renderer_native,
|
||||
data->in_kms_update,
|
||||
crtc);
|
||||
META_CRTC_KMS (crtc));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@@ -501,7 +509,8 @@ static void
|
||||
disable_hw_cursor_for_crtc (MetaKmsCrtc *kms_crtc,
|
||||
const GError *error)
|
||||
{
|
||||
MetaCrtc *crtc = meta_crtc_kms_from_kms_crtc (kms_crtc);
|
||||
MetaCrtcKms *crtc_kms = meta_crtc_kms_from_kms_crtc (kms_crtc);
|
||||
MetaCrtc *crtc = META_CRTC (crtc_kms);
|
||||
MetaGpuKms *gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc));
|
||||
MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data =
|
||||
meta_cursor_renderer_native_gpu_data_from_gpu (gpu_kms);
|
||||
@@ -691,7 +700,8 @@ has_cursor_plane (MetaLogicalMonitor *logical_monitor,
|
||||
gpointer user_data)
|
||||
{
|
||||
gboolean *has_cursor_planes = user_data;
|
||||
MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc);
|
||||
MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc);
|
||||
MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
|
||||
MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc);
|
||||
|
||||
*has_cursor_planes &= !!meta_kms_device_get_cursor_plane_for (kms_device,
|
||||
@@ -1049,10 +1059,12 @@ unset_crtc_cursor_renderer_privates (MetaGpu *gpu,
|
||||
|
||||
for (l = meta_gpu_get_crtcs (gpu); l; l = l->next)
|
||||
{
|
||||
MetaCrtc *crtc = l->data;
|
||||
MetaCrtcKms *crtc_kms = META_CRTC_KMS (l->data);
|
||||
struct gbm_bo *crtc_bo;
|
||||
|
||||
if (bo == crtc->cursor_renderer_private)
|
||||
crtc->cursor_renderer_private = NULL;
|
||||
crtc_bo = meta_crtc_kms_get_cursor_renderer_private (crtc_kms);
|
||||
if (bo == crtc_bo)
|
||||
meta_crtc_kms_set_cursor_renderer_private (crtc_kms, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1719,8 +1731,9 @@ meta_cursor_renderer_native_new (MetaBackend *backend)
|
||||
MetaCursorRendererNative *cursor_renderer_native;
|
||||
MetaCursorRendererNativePrivate *priv;
|
||||
|
||||
cursor_renderer_native =
|
||||
g_object_new (META_TYPE_CURSOR_RENDERER_NATIVE, NULL);
|
||||
cursor_renderer_native = g_object_new (META_TYPE_CURSOR_RENDERER_NATIVE,
|
||||
"backend", backend,
|
||||
NULL);
|
||||
priv =
|
||||
meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
|
||||
|
||||
|
@@ -38,6 +38,7 @@
|
||||
#include "backends/meta-output.h"
|
||||
#include "backends/native/meta-backend-native.h"
|
||||
#include "backends/native/meta-crtc-kms.h"
|
||||
#include "backends/native/meta-crtc-mode-kms.h"
|
||||
#include "backends/native/meta-kms-connector.h"
|
||||
#include "backends/native/meta-kms-device.h"
|
||||
#include "backends/native/meta-kms-update.h"
|
||||
@@ -232,13 +233,28 @@ meta_gpu_kms_set_power_save_mode (MetaGpuKms *gpu_kms,
|
||||
uint64_t state,
|
||||
MetaKmsUpdate *kms_update)
|
||||
{
|
||||
MetaGpu *gpu = META_GPU (gpu_kms);
|
||||
GList *l;
|
||||
|
||||
for (l = meta_gpu_get_outputs (META_GPU (gpu_kms)); l; l = l->next)
|
||||
for (l = meta_gpu_get_outputs (gpu); l; l = l->next)
|
||||
{
|
||||
MetaOutput *output = l->data;
|
||||
|
||||
meta_output_kms_set_power_save_mode (output, state, kms_update);
|
||||
meta_output_kms_set_power_save_mode (META_OUTPUT_KMS (output),
|
||||
state, kms_update);
|
||||
}
|
||||
|
||||
if (state != META_POWER_SAVE_ON)
|
||||
{
|
||||
/* Turn off CRTCs for DPMS */
|
||||
for (l = meta_gpu_get_crtcs (gpu); l; l = l->next)
|
||||
{
|
||||
MetaCrtcKms *crtc_kms = META_CRTC_KMS (l->data);
|
||||
|
||||
meta_kms_update_mode_set (kms_update,
|
||||
meta_crtc_kms_get_kms_crtc (crtc_kms),
|
||||
NULL, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,15 +280,12 @@ static int
|
||||
compare_outputs (gconstpointer one,
|
||||
gconstpointer two)
|
||||
{
|
||||
const MetaOutput *o_one = one, *o_two = two;
|
||||
MetaOutput *o_one = (MetaOutput *) one;
|
||||
MetaOutput *o_two = (MetaOutput *) two;
|
||||
const MetaOutputInfo *output_info_one = meta_output_get_info (o_one);
|
||||
const MetaOutputInfo *output_info_two = meta_output_get_info (o_two);
|
||||
|
||||
return strcmp (o_one->name, o_two->name);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_crtc_mode_destroy_notify (MetaCrtcMode *mode)
|
||||
{
|
||||
g_slice_free (drmModeModeInfo, mode->driver_private);
|
||||
return strcmp (output_info_one->name, output_info_two->name);
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -325,35 +338,17 @@ meta_gpu_kms_get_mode_from_drm_mode (MetaGpuKms *gpu_kms,
|
||||
|
||||
for (l = meta_gpu_get_modes (gpu); l; l = l->next)
|
||||
{
|
||||
MetaCrtcMode *mode = l->data;
|
||||
MetaCrtcModeKms *crtc_mode_kms = l->data;
|
||||
|
||||
if (meta_drm_mode_equal (drm_mode, mode->driver_private))
|
||||
return mode;
|
||||
if (meta_drm_mode_equal (drm_mode,
|
||||
meta_crtc_mode_kms_get_drm_mode (crtc_mode_kms)))
|
||||
return META_CRTC_MODE (crtc_mode_kms);
|
||||
}
|
||||
|
||||
g_assert_not_reached ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static MetaCrtcMode *
|
||||
create_mode (const drmModeModeInfo *drm_mode,
|
||||
long mode_id)
|
||||
{
|
||||
MetaCrtcMode *mode;
|
||||
|
||||
mode = g_object_new (META_TYPE_CRTC_MODE, NULL);
|
||||
mode->mode_id = mode_id;
|
||||
mode->name = g_strndup (drm_mode->name, DRM_DISPLAY_MODE_LEN);
|
||||
mode->width = drm_mode->hdisplay;
|
||||
mode->height = drm_mode->vdisplay;
|
||||
mode->flags = drm_mode->flags;
|
||||
mode->refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode);
|
||||
mode->driver_private = g_slice_dup (drmModeModeInfo, drm_mode);
|
||||
mode->driver_notify = (GDestroyNotify) meta_crtc_mode_destroy_notify;
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
static MetaOutput *
|
||||
find_output_by_connector_id (GList *outputs,
|
||||
uint32_t connector_id)
|
||||
@@ -364,7 +359,8 @@ find_output_by_connector_id (GList *outputs,
|
||||
{
|
||||
MetaOutput *output = l->data;
|
||||
|
||||
if (meta_output_kms_get_connector_id (output) == connector_id)
|
||||
if (meta_output_kms_get_connector_id (META_OUTPUT_KMS (output)) ==
|
||||
connector_id)
|
||||
return output;
|
||||
}
|
||||
|
||||
@@ -388,15 +384,9 @@ setup_output_clones (MetaGpu *gpu)
|
||||
if (other_output == output)
|
||||
continue;
|
||||
|
||||
if (meta_output_kms_can_clone (output, other_output))
|
||||
{
|
||||
output->n_possible_clones++;
|
||||
output->possible_clones = g_renew (MetaOutput *,
|
||||
output->possible_clones,
|
||||
output->n_possible_clones);
|
||||
output->possible_clones[output->n_possible_clones - 1] =
|
||||
other_output;
|
||||
}
|
||||
if (meta_output_kms_can_clone (META_OUTPUT_KMS (output),
|
||||
META_OUTPUT_KMS (other_output)))
|
||||
meta_output_add_possible_clone (output, other_output);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -436,9 +426,9 @@ init_modes (MetaGpuKms *gpu_kms)
|
||||
mode_id = 0;
|
||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &drm_mode))
|
||||
{
|
||||
MetaCrtcMode *mode;
|
||||
MetaCrtcModeKms *mode;
|
||||
|
||||
mode = create_mode (drm_mode, (long) mode_id);
|
||||
mode = meta_crtc_mode_kms_new (drm_mode, (long) mode_id);
|
||||
modes = g_list_append (modes, mode);
|
||||
|
||||
mode_id++;
|
||||
@@ -448,9 +438,10 @@ init_modes (MetaGpuKms *gpu_kms)
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (meta_default_landscape_drm_mode_infos); i++)
|
||||
{
|
||||
MetaCrtcMode *mode;
|
||||
MetaCrtcModeKms *mode;
|
||||
|
||||
mode = create_mode (&meta_default_landscape_drm_mode_infos[i], mode_id);
|
||||
mode = meta_crtc_mode_kms_new (&meta_default_landscape_drm_mode_infos[i],
|
||||
mode_id);
|
||||
modes = g_list_append (modes, mode);
|
||||
|
||||
mode_id++;
|
||||
@@ -458,9 +449,10 @@ init_modes (MetaGpuKms *gpu_kms)
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (meta_default_portrait_drm_mode_infos); i++)
|
||||
{
|
||||
MetaCrtcMode *mode;
|
||||
MetaCrtcModeKms *mode;
|
||||
|
||||
mode = create_mode (&meta_default_portrait_drm_mode_infos[i], mode_id);
|
||||
mode = meta_crtc_mode_kms_new (&meta_default_portrait_drm_mode_infos[i],
|
||||
mode_id);
|
||||
modes = g_list_append (modes, mode);
|
||||
|
||||
mode_id++;
|
||||
@@ -482,11 +474,11 @@ init_crtcs (MetaGpuKms *gpu_kms)
|
||||
for (l = meta_kms_device_get_crtcs (kms_device); l; l = l->next)
|
||||
{
|
||||
MetaKmsCrtc *kms_crtc = l->data;
|
||||
MetaCrtc *crtc;
|
||||
MetaCrtcKms *crtc_kms;
|
||||
|
||||
crtc = meta_create_kms_crtc (gpu_kms, kms_crtc);
|
||||
crtc_kms = meta_crtc_kms_new (gpu_kms, kms_crtc);
|
||||
|
||||
crtcs = g_list_append (crtcs, crtc);
|
||||
crtcs = g_list_append (crtcs, crtc_kms);
|
||||
}
|
||||
|
||||
meta_gpu_take_crtcs (gpu, crtcs);
|
||||
@@ -519,7 +511,7 @@ init_outputs (MetaGpuKms *gpu_kms)
|
||||
{
|
||||
MetaKmsConnector *kms_connector = l->data;
|
||||
const MetaKmsConnectorState *connector_state;
|
||||
MetaOutput *output;
|
||||
MetaOutputKms *output_kms;
|
||||
MetaOutput *old_output;
|
||||
GError *error = NULL;
|
||||
|
||||
@@ -530,18 +522,18 @@ init_outputs (MetaGpuKms *gpu_kms)
|
||||
old_output =
|
||||
find_output_by_connector_id (old_outputs,
|
||||
meta_kms_connector_get_id (kms_connector));
|
||||
output = meta_create_kms_output (gpu_kms,
|
||||
kms_connector,
|
||||
old_output,
|
||||
&error);
|
||||
if (!output)
|
||||
output_kms = meta_output_kms_new (gpu_kms,
|
||||
kms_connector,
|
||||
old_output,
|
||||
&error);
|
||||
if (!output_kms)
|
||||
{
|
||||
g_warning ("Failed to create KMS output: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
else
|
||||
{
|
||||
outputs = g_list_prepend (outputs, output);
|
||||
outputs = g_list_prepend (outputs, output_kms);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -69,6 +69,7 @@ meta_input_device_native_finalize (GObject *object)
|
||||
|
||||
meta_input_device_native_release_touch_slots (device_evdev,
|
||||
g_get_monotonic_time ());
|
||||
g_clear_pointer (&device_evdev->touches, g_hash_table_unref);
|
||||
|
||||
backend = clutter_get_default_backend ();
|
||||
seat = clutter_backend_get_default_seat (backend);
|
||||
|
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "backends/meta-keymap-utils.h"
|
||||
#include "backends/native/meta-keymap-native.h"
|
||||
#include "backends/native/meta-seat-native.h"
|
||||
|
||||
@@ -111,7 +112,7 @@ meta_keymap_native_init (MetaKeymapNative *keymap)
|
||||
names.variant = option_xkb_variant;
|
||||
names.options = option_xkb_options;
|
||||
|
||||
ctx = xkb_context_new (XKB_CONTEXT_NO_FLAGS);
|
||||
ctx = meta_create_xkb_context ();
|
||||
g_assert (ctx);
|
||||
keymap->keymap = xkb_keymap_new_from_names (ctx, &names, 0);
|
||||
xkb_context_unref (ctx);
|
||||
|
@@ -208,10 +208,10 @@ meta_kms_update_unassign_plane (MetaKmsUpdate *update,
|
||||
}
|
||||
|
||||
void
|
||||
meta_kms_update_mode_set (MetaKmsUpdate *update,
|
||||
MetaKmsCrtc *crtc,
|
||||
GList *connectors,
|
||||
drmModeModeInfo *drm_mode)
|
||||
meta_kms_update_mode_set (MetaKmsUpdate *update,
|
||||
MetaKmsCrtc *crtc,
|
||||
GList *connectors,
|
||||
const drmModeModeInfo *drm_mode)
|
||||
{
|
||||
MetaKmsModeSet *mode_set;
|
||||
|
||||
|
@@ -79,10 +79,10 @@ MetaKmsUpdate * meta_kms_update_new (void);
|
||||
|
||||
void meta_kms_update_free (MetaKmsUpdate *update);
|
||||
|
||||
void meta_kms_update_mode_set (MetaKmsUpdate *update,
|
||||
MetaKmsCrtc *crtc,
|
||||
GList *connectors,
|
||||
drmModeModeInfo *drm_mode);
|
||||
void meta_kms_update_mode_set (MetaKmsUpdate *update,
|
||||
MetaKmsCrtc *crtc,
|
||||
GList *connectors,
|
||||
const drmModeModeInfo *drm_mode);
|
||||
|
||||
MetaKmsPlaneAssignment * meta_kms_update_assign_plane (MetaKmsUpdate *update,
|
||||
MetaKmsCrtc *crtc,
|
||||
|
@@ -95,7 +95,7 @@ static GBytes *
|
||||
meta_monitor_manager_kms_read_edid (MetaMonitorManager *manager,
|
||||
MetaOutput *output)
|
||||
{
|
||||
return meta_output_kms_read_edid (output);
|
||||
return meta_output_kms_read_edid (META_OUTPUT_KMS (output));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -169,25 +169,41 @@ meta_monitor_manager_kms_ensure_initial_config (MetaMonitorManager *manager)
|
||||
}
|
||||
|
||||
static void
|
||||
apply_crtc_assignments (MetaMonitorManager *manager,
|
||||
MetaCrtcInfo **crtcs,
|
||||
unsigned int n_crtcs,
|
||||
MetaOutputInfo **outputs,
|
||||
unsigned int n_outputs)
|
||||
apply_crtc_assignments (MetaMonitorManager *manager,
|
||||
MetaCrtcAssignment **crtcs,
|
||||
unsigned int n_crtcs,
|
||||
MetaOutputAssignment **outputs,
|
||||
unsigned int n_outputs)
|
||||
{
|
||||
MetaBackend *backend = meta_monitor_manager_get_backend (manager);
|
||||
g_autoptr (GList) to_configure_outputs = NULL;
|
||||
g_autoptr (GList) to_configure_crtcs = NULL;
|
||||
unsigned i;
|
||||
GList *gpus;
|
||||
GList *l;
|
||||
|
||||
gpus = meta_backend_get_gpus (backend);
|
||||
for (l = gpus; l; l = l->next)
|
||||
{
|
||||
MetaGpu *gpu = l->data;
|
||||
GList *crtcs;
|
||||
GList *outputs;
|
||||
|
||||
outputs = g_list_copy (meta_gpu_get_outputs (gpu));
|
||||
to_configure_outputs = g_list_concat (to_configure_outputs, outputs);
|
||||
|
||||
crtcs = g_list_copy (meta_gpu_get_crtcs (gpu));
|
||||
to_configure_crtcs = g_list_concat (to_configure_crtcs, crtcs);
|
||||
}
|
||||
|
||||
for (i = 0; i < n_crtcs; i++)
|
||||
{
|
||||
MetaCrtcInfo *crtc_info = crtcs[i];
|
||||
MetaCrtc *crtc = crtc_info->crtc;
|
||||
MetaCrtcAssignment *crtc_assignment = crtcs[i];
|
||||
MetaCrtc *crtc = crtc_assignment->crtc;
|
||||
|
||||
crtc->is_dirty = TRUE;
|
||||
to_configure_crtcs = g_list_remove (to_configure_crtcs, crtc);
|
||||
|
||||
if (crtc_info->mode == NULL)
|
||||
if (crtc_assignment->mode == NULL)
|
||||
{
|
||||
meta_crtc_unset_config (crtc);
|
||||
}
|
||||
@@ -196,71 +212,33 @@ apply_crtc_assignments (MetaMonitorManager *manager,
|
||||
unsigned int j;
|
||||
|
||||
meta_crtc_set_config (crtc,
|
||||
&crtc_info->layout,
|
||||
crtc_info->mode,
|
||||
crtc_info->transform);
|
||||
&crtc_assignment->layout,
|
||||
crtc_assignment->mode,
|
||||
crtc_assignment->transform);
|
||||
|
||||
for (j = 0; j < crtc_info->outputs->len; j++)
|
||||
for (j = 0; j < crtc_assignment->outputs->len; j++)
|
||||
{
|
||||
MetaOutput *output = g_ptr_array_index (crtc_info->outputs, j);
|
||||
MetaOutput *output = g_ptr_array_index (crtc_assignment->outputs,
|
||||
j);
|
||||
MetaOutputAssignment *output_assignment;
|
||||
|
||||
output->is_dirty = TRUE;
|
||||
meta_output_assign_crtc (output, crtc);
|
||||
to_configure_outputs = g_list_remove (to_configure_outputs,
|
||||
output);
|
||||
|
||||
output_assignment = meta_find_output_assignment (outputs,
|
||||
n_outputs,
|
||||
output);
|
||||
meta_output_assign_crtc (output, crtc, output_assignment);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Disable CRTCs not mentioned in the list (they have is_dirty == FALSE,
|
||||
because they weren't seen in the first loop) */
|
||||
gpus = meta_backend_get_gpus (backend);
|
||||
for (l = gpus; l; l = l->next)
|
||||
{
|
||||
MetaGpu *gpu = l->data;
|
||||
GList *k;
|
||||
|
||||
for (k = meta_gpu_get_crtcs (gpu); k; k = k->next)
|
||||
{
|
||||
MetaCrtc *crtc = k->data;
|
||||
|
||||
if (crtc->is_dirty)
|
||||
{
|
||||
crtc->is_dirty = FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
meta_crtc_unset_config (crtc);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
{
|
||||
MetaOutputInfo *output_info = outputs[i];
|
||||
MetaOutput *output = output_info->output;
|
||||
|
||||
output->is_primary = output_info->is_primary;
|
||||
output->is_presentation = output_info->is_presentation;
|
||||
output->is_underscanning = output_info->is_underscanning;
|
||||
}
|
||||
|
||||
/* Disable outputs not mentioned in the list */
|
||||
for (l = gpus; l; l = l->next)
|
||||
{
|
||||
MetaGpu *gpu = l->data;
|
||||
GList *k;
|
||||
|
||||
for (k = meta_gpu_get_outputs (gpu); k; k = k->next)
|
||||
{
|
||||
MetaOutput *output = k->data;
|
||||
|
||||
if (output->is_dirty)
|
||||
{
|
||||
output->is_dirty = FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
meta_output_unassign_crtc (output);
|
||||
output->is_primary = FALSE;
|
||||
}
|
||||
}
|
||||
g_list_foreach (to_configure_crtcs,
|
||||
(GFunc) meta_crtc_unset_config,
|
||||
NULL);
|
||||
g_list_foreach (to_configure_outputs,
|
||||
(GFunc) meta_output_unassign_crtc,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -298,8 +276,8 @@ meta_monitor_manager_kms_apply_monitors_config (MetaMonitorManager *manager
|
||||
MetaMonitorsConfigMethod method,
|
||||
GError **error)
|
||||
{
|
||||
GPtrArray *crtc_infos;
|
||||
GPtrArray *output_infos;
|
||||
GPtrArray *crtc_assignments;
|
||||
GPtrArray *output_assignments;
|
||||
|
||||
if (!config)
|
||||
{
|
||||
@@ -310,25 +288,26 @@ meta_monitor_manager_kms_apply_monitors_config (MetaMonitorManager *manager
|
||||
}
|
||||
|
||||
if (!meta_monitor_config_manager_assign (manager, config,
|
||||
&crtc_infos, &output_infos,
|
||||
&crtc_assignments,
|
||||
&output_assignments,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
if (method == META_MONITORS_CONFIG_METHOD_VERIFY)
|
||||
{
|
||||
g_ptr_array_free (crtc_infos, TRUE);
|
||||
g_ptr_array_free (output_infos, TRUE);
|
||||
g_ptr_array_free (crtc_assignments, TRUE);
|
||||
g_ptr_array_free (output_assignments, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
apply_crtc_assignments (manager,
|
||||
(MetaCrtcInfo **) crtc_infos->pdata,
|
||||
crtc_infos->len,
|
||||
(MetaOutputInfo **) output_infos->pdata,
|
||||
output_infos->len);
|
||||
(MetaCrtcAssignment **) crtc_assignments->pdata,
|
||||
crtc_assignments->len,
|
||||
(MetaOutputAssignment **) output_assignments->pdata,
|
||||
output_assignments->len);
|
||||
|
||||
g_ptr_array_free (crtc_infos, TRUE);
|
||||
g_ptr_array_free (output_infos, TRUE);
|
||||
g_ptr_array_free (crtc_assignments, TRUE);
|
||||
g_ptr_array_free (output_assignments, TRUE);
|
||||
|
||||
update_screen_size (manager, config);
|
||||
meta_monitor_manager_rebuild (manager, config);
|
||||
@@ -347,7 +326,7 @@ meta_monitor_manager_kms_get_crtc_gamma (MetaMonitorManager *manager,
|
||||
MetaKmsCrtc *kms_crtc;
|
||||
const MetaKmsCrtcState *crtc_state;
|
||||
|
||||
kms_crtc = meta_crtc_kms_get_kms_crtc (crtc);
|
||||
kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc));
|
||||
crtc_state = meta_kms_crtc_get_current_state (kms_crtc);
|
||||
|
||||
*size = crtc_state->gamma.size;
|
||||
@@ -435,11 +414,12 @@ meta_monitor_manager_kms_set_crtc_gamma (MetaMonitorManager *manager,
|
||||
g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
|
||||
|
||||
gamma_ramp_string = generate_gamma_ramp_string (size, red, green, blue);
|
||||
g_debug ("Setting CRTC (%ld) gamma to %s", crtc->crtc_id, gamma_ramp_string);
|
||||
g_debug ("Setting CRTC (%ld) gamma to %s",
|
||||
meta_crtc_get_id (crtc), gamma_ramp_string);
|
||||
|
||||
kms_update = meta_kms_ensure_pending_update (kms);
|
||||
|
||||
kms_crtc = meta_crtc_kms_get_kms_crtc (crtc);
|
||||
kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc));
|
||||
meta_kms_crtc_set_gamma (kms_crtc, kms_update,
|
||||
size, red, green, blue);
|
||||
|
||||
@@ -507,7 +487,7 @@ meta_monitor_manager_kms_is_transform_handled (MetaMonitorManager *manager,
|
||||
MetaCrtc *crtc,
|
||||
MetaMonitorTransform transform)
|
||||
{
|
||||
return meta_crtc_kms_is_transform_handled (crtc, transform);
|
||||
return meta_crtc_kms_is_transform_handled (META_CRTC_KMS (crtc), transform);
|
||||
}
|
||||
|
||||
static float
|
||||
|
@@ -32,6 +32,7 @@
|
||||
#include "backends/native/meta-kms-connector.h"
|
||||
#include "backends/native/meta-kms-utils.h"
|
||||
#include "backends/native/meta-crtc-kms.h"
|
||||
#include "backends/native/meta-crtc-mode-kms.h"
|
||||
|
||||
#include "meta-default-modes.h"
|
||||
|
||||
@@ -44,33 +45,37 @@ typedef struct _MetaOutputKms
|
||||
MetaKmsConnector *kms_connector;
|
||||
} MetaOutputKms;
|
||||
|
||||
MetaKmsConnector *
|
||||
meta_output_kms_get_kms_connector (MetaOutput *output)
|
||||
{
|
||||
MetaOutputKms *output_kms = output->driver_private;
|
||||
G_DEFINE_TYPE (MetaOutputKms, meta_output_kms, META_TYPE_OUTPUT)
|
||||
|
||||
MetaKmsConnector *
|
||||
meta_output_kms_get_kms_connector (MetaOutputKms *output_kms)
|
||||
{
|
||||
return output_kms->kms_connector;
|
||||
}
|
||||
|
||||
void
|
||||
meta_output_kms_set_underscan (MetaOutput *output,
|
||||
meta_output_kms_set_underscan (MetaOutputKms *output_kms,
|
||||
MetaKmsUpdate *kms_update)
|
||||
{
|
||||
MetaOutputKms *output_kms = output->driver_private;
|
||||
MetaOutput *output = META_OUTPUT (output_kms);
|
||||
const MetaOutputInfo *output_info = meta_output_get_info (output);
|
||||
|
||||
if (!output->supports_underscanning)
|
||||
if (!output_info->supports_underscanning)
|
||||
return;
|
||||
|
||||
if (output->is_underscanning)
|
||||
if (meta_output_is_underscanning (output))
|
||||
{
|
||||
MetaCrtc *crtc;
|
||||
MetaCrtcConfig *crtc_config;
|
||||
const MetaCrtcConfig *crtc_config;
|
||||
const MetaCrtcModeInfo *crtc_mode_info;
|
||||
uint64_t hborder, vborder;
|
||||
|
||||
crtc = meta_output_get_assigned_crtc (output);
|
||||
crtc_config = crtc->config;
|
||||
hborder = MIN (128, (uint64_t) round (crtc_config->mode->width * 0.05));
|
||||
vborder = MIN (128, (uint64_t) round (crtc_config->mode->height * 0.05));
|
||||
crtc_config = meta_crtc_get_config (crtc);
|
||||
crtc_mode_info = meta_crtc_mode_get_info (crtc_config->mode);
|
||||
|
||||
hborder = MIN (128, (uint64_t) round (crtc_mode_info->width * 0.05));
|
||||
vborder = MIN (128, (uint64_t) round (crtc_mode_info->height * 0.05));
|
||||
|
||||
g_debug ("Setting underscan of connector %s to %" G_GUINT64_FORMAT " x %" G_GUINT64_FORMAT,
|
||||
meta_kms_connector_get_name (output_kms->kms_connector),
|
||||
@@ -92,20 +97,16 @@ meta_output_kms_set_underscan (MetaOutput *output,
|
||||
}
|
||||
|
||||
uint32_t
|
||||
meta_output_kms_get_connector_id (MetaOutput *output)
|
||||
meta_output_kms_get_connector_id (MetaOutputKms *output_kms)
|
||||
{
|
||||
MetaOutputKms *output_kms = output->driver_private;
|
||||
|
||||
return meta_kms_connector_get_id (output_kms->kms_connector);
|
||||
}
|
||||
|
||||
void
|
||||
meta_output_kms_set_power_save_mode (MetaOutput *output,
|
||||
meta_output_kms_set_power_save_mode (MetaOutputKms *output_kms,
|
||||
uint64_t dpms_state,
|
||||
MetaKmsUpdate *kms_update)
|
||||
{
|
||||
MetaOutputKms *output_kms = output->driver_private;
|
||||
|
||||
g_debug ("Setting DPMS state of connector %s to %" G_GUINT64_FORMAT,
|
||||
meta_kms_connector_get_name (output_kms->kms_connector),
|
||||
dpms_state);
|
||||
@@ -116,20 +117,16 @@ meta_output_kms_set_power_save_mode (MetaOutput *output,
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_output_kms_can_clone (MetaOutput *output,
|
||||
MetaOutput *other_output)
|
||||
meta_output_kms_can_clone (MetaOutputKms *output_kms,
|
||||
MetaOutputKms *other_output_kms)
|
||||
{
|
||||
MetaOutputKms *output_kms = output->driver_private;
|
||||
MetaOutputKms *other_output_kms = other_output->driver_private;
|
||||
|
||||
return meta_kms_connector_can_clone (output_kms->kms_connector,
|
||||
other_output_kms->kms_connector);
|
||||
}
|
||||
|
||||
GBytes *
|
||||
meta_output_kms_read_edid (MetaOutput *output)
|
||||
meta_output_kms_read_edid (MetaOutputKms *output_kms)
|
||||
{
|
||||
MetaOutputKms *output_kms = output->driver_private;
|
||||
const MetaKmsConnectorState *connector_state;
|
||||
GBytes *edid_data;
|
||||
|
||||
@@ -143,18 +140,8 @@ meta_output_kms_read_edid (MetaOutput *output)
|
||||
}
|
||||
|
||||
static void
|
||||
meta_output_destroy_notify (MetaOutput *output)
|
||||
{
|
||||
MetaOutputKms *output_kms;
|
||||
|
||||
output_kms = output->driver_private;
|
||||
|
||||
g_slice_free (MetaOutputKms, output_kms);
|
||||
}
|
||||
|
||||
static void
|
||||
add_common_modes (MetaOutput *output,
|
||||
MetaGpuKms *gpu_kms)
|
||||
add_common_modes (MetaOutputInfo *output_info,
|
||||
MetaGpuKms *gpu_kms)
|
||||
{
|
||||
const drmModeModeInfo *drm_mode;
|
||||
MetaCrtcMode *crtc_mode;
|
||||
@@ -165,9 +152,12 @@ add_common_modes (MetaOutput *output,
|
||||
unsigned max_vdisplay = 0;
|
||||
float max_refresh_rate = 0.0;
|
||||
|
||||
for (i = 0; i < output->n_modes; i++)
|
||||
for (i = 0; i < output_info->n_modes; i++)
|
||||
{
|
||||
drm_mode = output->modes[i]->driver_private;
|
||||
MetaCrtcMode *crtc_mode = output_info->modes[i];
|
||||
MetaCrtcModeKms *crtc_mode_kms = META_CRTC_MODE_KMS (crtc_mode);
|
||||
|
||||
drm_mode = meta_crtc_mode_kms_get_drm_mode (crtc_mode_kms);
|
||||
refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode);
|
||||
max_hdisplay = MAX (max_hdisplay, drm_mode->hdisplay);
|
||||
max_vdisplay = MAX (max_vdisplay, drm_mode->vdisplay);
|
||||
@@ -211,11 +201,11 @@ add_common_modes (MetaOutput *output,
|
||||
}
|
||||
}
|
||||
|
||||
output->modes = g_renew (MetaCrtcMode *, output->modes,
|
||||
output->n_modes + array->len);
|
||||
memcpy (output->modes + output->n_modes, array->pdata,
|
||||
output_info->modes = g_renew (MetaCrtcMode *, output_info->modes,
|
||||
output_info->n_modes + array->len);
|
||||
memcpy (output_info->modes + output_info->n_modes, array->pdata,
|
||||
array->len * sizeof (MetaCrtcMode *));
|
||||
output->n_modes += array->len;
|
||||
output_info->n_modes += array->len;
|
||||
|
||||
g_ptr_array_free (array, TRUE);
|
||||
}
|
||||
@@ -224,135 +214,148 @@ static int
|
||||
compare_modes (const void *one,
|
||||
const void *two)
|
||||
{
|
||||
MetaCrtcMode *a = *(MetaCrtcMode **) one;
|
||||
MetaCrtcMode *b = *(MetaCrtcMode **) two;
|
||||
MetaCrtcMode *crtc_mode_one = *(MetaCrtcMode **) one;
|
||||
MetaCrtcMode *crtc_mode_two = *(MetaCrtcMode **) two;
|
||||
const MetaCrtcModeInfo *crtc_mode_info_one =
|
||||
meta_crtc_mode_get_info (crtc_mode_one);
|
||||
const MetaCrtcModeInfo *crtc_mode_info_two =
|
||||
meta_crtc_mode_get_info (crtc_mode_two);
|
||||
|
||||
if (a->width != b->width)
|
||||
return a->width > b->width ? -1 : 1;
|
||||
if (a->height != b->height)
|
||||
return a->height > b->height ? -1 : 1;
|
||||
if (a->refresh_rate != b->refresh_rate)
|
||||
return a->refresh_rate > b->refresh_rate ? -1 : 1;
|
||||
if (crtc_mode_info_one->width != crtc_mode_info_two->width)
|
||||
return crtc_mode_info_one->width > crtc_mode_info_two->width ? -1 : 1;
|
||||
if (crtc_mode_info_one->height != crtc_mode_info_two->height)
|
||||
return crtc_mode_info_one->height > crtc_mode_info_two->height ? -1 : 1;
|
||||
if (crtc_mode_info_one->refresh_rate != crtc_mode_info_two->refresh_rate)
|
||||
return (crtc_mode_info_one->refresh_rate > crtc_mode_info_two->refresh_rate
|
||||
? -1 : 1);
|
||||
|
||||
return g_strcmp0 (b->name, a->name);
|
||||
return g_strcmp0 (meta_crtc_mode_get_name (crtc_mode_one),
|
||||
meta_crtc_mode_get_name (crtc_mode_two));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
init_output_modes (MetaOutput *output,
|
||||
MetaGpuKms *gpu_kms,
|
||||
GError **error)
|
||||
init_output_modes (MetaOutputInfo *output_info,
|
||||
MetaGpuKms *gpu_kms,
|
||||
MetaKmsConnector *kms_connector,
|
||||
GError **error)
|
||||
{
|
||||
MetaOutputKms *output_kms = output->driver_private;
|
||||
const MetaKmsConnectorState *connector_state;
|
||||
int i;
|
||||
|
||||
connector_state =
|
||||
meta_kms_connector_get_current_state (output_kms->kms_connector);
|
||||
connector_state = meta_kms_connector_get_current_state (kms_connector);
|
||||
|
||||
output->preferred_mode = NULL;
|
||||
output_info->preferred_mode = NULL;
|
||||
|
||||
output->n_modes = connector_state->n_modes;
|
||||
output->modes = g_new0 (MetaCrtcMode *, output->n_modes);
|
||||
output_info->n_modes = connector_state->n_modes;
|
||||
output_info->modes = g_new0 (MetaCrtcMode *, output_info->n_modes);
|
||||
for (i = 0; i < connector_state->n_modes; i++)
|
||||
{
|
||||
drmModeModeInfo *drm_mode = &connector_state->modes[i];
|
||||
MetaCrtcMode *crtc_mode;
|
||||
|
||||
crtc_mode = meta_gpu_kms_get_mode_from_drm_mode (gpu_kms, drm_mode);
|
||||
output->modes[i] = crtc_mode;
|
||||
output_info->modes[i] = crtc_mode;
|
||||
if (drm_mode->type & DRM_MODE_TYPE_PREFERRED)
|
||||
output->preferred_mode = output->modes[i];
|
||||
output_info->preferred_mode = output_info->modes[i];
|
||||
}
|
||||
|
||||
/* FIXME: MSC feature bit? */
|
||||
/* Presume that if the output supports scaling, then we have
|
||||
* a panel fitter capable of adjusting any mode to suit.
|
||||
*/
|
||||
if (connector_state->has_scaling)
|
||||
add_common_modes (output, gpu_kms);
|
||||
add_common_modes (output_info, gpu_kms);
|
||||
|
||||
if (!output->modes)
|
||||
if (!output_info->modes)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"No modes available");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
qsort (output->modes, output->n_modes,
|
||||
qsort (output_info->modes, output_info->n_modes,
|
||||
sizeof (MetaCrtcMode *), compare_modes);
|
||||
|
||||
if (!output->preferred_mode)
|
||||
output->preferred_mode = output->modes[0];
|
||||
if (!output_info->preferred_mode)
|
||||
output_info->preferred_mode = output_info->modes[0];
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
MetaOutput *
|
||||
meta_create_kms_output (MetaGpuKms *gpu_kms,
|
||||
MetaKmsConnector *kms_connector,
|
||||
MetaOutput *old_output,
|
||||
GError **error)
|
||||
MetaOutputKms *
|
||||
meta_output_kms_new (MetaGpuKms *gpu_kms,
|
||||
MetaKmsConnector *kms_connector,
|
||||
MetaOutput *old_output,
|
||||
GError **error)
|
||||
{
|
||||
MetaGpu *gpu = META_GPU (gpu_kms);
|
||||
uint32_t connector_id;
|
||||
uint32_t gpu_id;
|
||||
g_autoptr (MetaOutputInfo) output_info = NULL;
|
||||
MetaOutput *output;
|
||||
MetaOutputKms *output_kms;
|
||||
const MetaKmsConnectorState *connector_state;
|
||||
uint32_t connector_id;
|
||||
GArray *crtcs;
|
||||
GList *l;
|
||||
uint32_t gpu_id;
|
||||
|
||||
output = g_object_new (META_TYPE_OUTPUT, NULL);
|
||||
|
||||
output_kms = g_slice_new0 (MetaOutputKms);
|
||||
output->driver_private = output_kms;
|
||||
output->driver_notify = (GDestroyNotify) meta_output_destroy_notify;
|
||||
|
||||
output->gpu = gpu;
|
||||
output->name = g_strdup (meta_kms_connector_get_name (kms_connector));
|
||||
|
||||
gpu_id = meta_gpu_kms_get_id (gpu_kms);
|
||||
connector_id = meta_kms_connector_get_id (kms_connector);
|
||||
output->winsys_id = ((uint64_t) gpu_id << 32) | connector_id;
|
||||
|
||||
output_kms->kms_connector = kms_connector;
|
||||
output_info = meta_output_info_new ();
|
||||
output_info->name = g_strdup (meta_kms_connector_get_name (kms_connector));
|
||||
|
||||
connector_state = meta_kms_connector_get_current_state (kms_connector);
|
||||
|
||||
output->panel_orientation_transform =
|
||||
output_info->panel_orientation_transform =
|
||||
connector_state->panel_orientation_transform;
|
||||
if (meta_monitor_transform_is_rotated (output->panel_orientation_transform))
|
||||
if (meta_monitor_transform_is_rotated (output_info->panel_orientation_transform))
|
||||
{
|
||||
output->width_mm = connector_state->height_mm;
|
||||
output->height_mm = connector_state->width_mm;
|
||||
output_info->width_mm = connector_state->height_mm;
|
||||
output_info->height_mm = connector_state->width_mm;
|
||||
}
|
||||
else
|
||||
{
|
||||
output->width_mm = connector_state->width_mm;
|
||||
output->height_mm = connector_state->height_mm;
|
||||
output_info->width_mm = connector_state->width_mm;
|
||||
output_info->height_mm = connector_state->height_mm;
|
||||
}
|
||||
|
||||
if (!init_output_modes (output, gpu_kms, error))
|
||||
{
|
||||
g_object_unref (output);
|
||||
return NULL;
|
||||
}
|
||||
if (!init_output_modes (output_info, gpu_kms, kms_connector, error))
|
||||
return NULL;
|
||||
|
||||
crtcs = g_array_new (FALSE, FALSE, sizeof (MetaCrtc *));
|
||||
|
||||
for (l = meta_gpu_get_crtcs (gpu); l; l = l->next)
|
||||
{
|
||||
MetaCrtc *crtc = l->data;
|
||||
MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc);
|
||||
MetaCrtcKms *crtc_kms = META_CRTC_KMS (l->data);
|
||||
MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
|
||||
uint32_t crtc_idx;
|
||||
|
||||
crtc_idx = meta_kms_crtc_get_idx (kms_crtc);
|
||||
if (connector_state->common_possible_crtcs & (1 << crtc_idx))
|
||||
g_array_append_val (crtcs, crtc);
|
||||
g_array_append_val (crtcs, crtc_kms);
|
||||
}
|
||||
|
||||
output->n_possible_crtcs = crtcs->len;
|
||||
output->possible_crtcs = (MetaCrtc **) g_array_free (crtcs, FALSE);
|
||||
output_info->n_possible_crtcs = crtcs->len;
|
||||
output_info->possible_crtcs = (MetaCrtc **) g_array_free (crtcs, FALSE);
|
||||
|
||||
output_info->suggested_x = connector_state->suggested_x;
|
||||
output_info->suggested_y = connector_state->suggested_y;
|
||||
output_info->hotplug_mode_update = connector_state->hotplug_mode_update;
|
||||
output_info->supports_underscanning =
|
||||
meta_kms_connector_is_underscanning_supported (kms_connector);
|
||||
|
||||
meta_output_info_parse_edid (output_info, connector_state->edid_data);
|
||||
|
||||
output_info->connector_type = meta_kms_connector_get_connector_type (kms_connector);
|
||||
|
||||
output_info->tile_info = connector_state->tile_info;
|
||||
|
||||
output = g_object_new (META_TYPE_OUTPUT_KMS,
|
||||
"id", ((uint64_t) gpu_id << 32) | connector_id,
|
||||
"gpu", gpu,
|
||||
"info", output_info,
|
||||
NULL);
|
||||
output_kms = META_OUTPUT_KMS (output);
|
||||
output_kms->kms_connector = kms_connector;
|
||||
|
||||
if (connector_state->current_crtc_id)
|
||||
{
|
||||
@@ -360,9 +363,25 @@ meta_create_kms_output (MetaGpuKms *gpu_kms,
|
||||
{
|
||||
MetaCrtc *crtc = l->data;
|
||||
|
||||
if (crtc->crtc_id == connector_state->current_crtc_id)
|
||||
if (meta_crtc_get_id (crtc) == connector_state->current_crtc_id)
|
||||
{
|
||||
meta_output_assign_crtc (output, crtc);
|
||||
MetaOutputAssignment output_assignment;
|
||||
|
||||
if (old_output)
|
||||
{
|
||||
output_assignment = (MetaOutputAssignment) {
|
||||
.is_primary = meta_output_is_primary (old_output),
|
||||
.is_presentation = meta_output_is_presentation (old_output),
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
output_assignment = (MetaOutputAssignment) {
|
||||
.is_primary = FALSE,
|
||||
.is_presentation = FALSE,
|
||||
};
|
||||
}
|
||||
meta_output_assign_crtc (output, crtc, &output_assignment);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -372,41 +391,15 @@ meta_create_kms_output (MetaGpuKms *gpu_kms,
|
||||
meta_output_unassign_crtc (output);
|
||||
}
|
||||
|
||||
if (old_output)
|
||||
{
|
||||
output->is_primary = old_output->is_primary;
|
||||
output->is_presentation = old_output->is_presentation;
|
||||
}
|
||||
else
|
||||
{
|
||||
output->is_primary = FALSE;
|
||||
output->is_presentation = FALSE;
|
||||
}
|
||||
|
||||
output->suggested_x = connector_state->suggested_x;
|
||||
output->suggested_y = connector_state->suggested_y;
|
||||
output->hotplug_mode_update = connector_state->hotplug_mode_update;
|
||||
output->supports_underscanning =
|
||||
meta_kms_connector_is_underscanning_supported (kms_connector);
|
||||
|
||||
meta_output_parse_edid (output, connector_state->edid_data);
|
||||
|
||||
output->connector_type = meta_kms_connector_get_connector_type (kms_connector);
|
||||
|
||||
output->tile_info = connector_state->tile_info;
|
||||
|
||||
/* FIXME: backlight is a very driver specific thing unfortunately,
|
||||
every DDX does its own thing, and the dumb KMS API does not include it.
|
||||
|
||||
For example, xf86-video-intel has a list of paths to probe in /sys/class/backlight
|
||||
(one for each major HW maker, and then some).
|
||||
We can't do the same because we're not root.
|
||||
It might be best to leave backlight out of the story and rely on the setuid
|
||||
helper in gnome-settings-daemon.
|
||||
*/
|
||||
output->backlight_min = 0;
|
||||
output->backlight_max = 0;
|
||||
output->backlight = -1;
|
||||
|
||||
return output;
|
||||
return output_kms;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_output_kms_init (MetaOutputKms *output_kms)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_output_kms_class_init (MetaOutputKmsClass *klass)
|
||||
{
|
||||
}
|
||||
|
@@ -27,23 +27,28 @@
|
||||
#include "backends/native/meta-gpu-kms.h"
|
||||
#include "backends/native/meta-kms-types.h"
|
||||
|
||||
void meta_output_kms_set_power_save_mode (MetaOutput *output,
|
||||
#define META_TYPE_OUTPUT_KMS (meta_output_kms_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaOutputKms, meta_output_kms,
|
||||
META, OUTPUT_KMS,
|
||||
MetaOutput)
|
||||
|
||||
void meta_output_kms_set_power_save_mode (MetaOutputKms *output_kms,
|
||||
uint64_t dpms_state,
|
||||
MetaKmsUpdate *kms_update);
|
||||
|
||||
void meta_output_kms_set_underscan (MetaOutput *output,
|
||||
void meta_output_kms_set_underscan (MetaOutputKms *output_kms,
|
||||
MetaKmsUpdate *kms_update);
|
||||
|
||||
gboolean meta_output_kms_can_clone (MetaOutput *output,
|
||||
MetaOutput *other_output);
|
||||
gboolean meta_output_kms_can_clone (MetaOutputKms *output_kms,
|
||||
MetaOutputKms *other_output_kms);
|
||||
|
||||
MetaKmsConnector * meta_output_kms_get_kms_connector (MetaOutput *output);
|
||||
MetaKmsConnector * meta_output_kms_get_kms_connector (MetaOutputKms *output_kms);
|
||||
|
||||
uint32_t meta_output_kms_get_connector_id (MetaOutput *output);
|
||||
uint32_t meta_output_kms_get_connector_id (MetaOutputKms *output_kms);
|
||||
|
||||
GBytes * meta_output_kms_read_edid (MetaOutput *output);
|
||||
GBytes * meta_output_kms_read_edid (MetaOutputKms *output_kms);
|
||||
|
||||
MetaOutput * meta_create_kms_output (MetaGpuKms *gpu_kms,
|
||||
MetaOutputKms * meta_output_kms_new (MetaGpuKms *gpu_kms,
|
||||
MetaKmsConnector *kms_connector,
|
||||
MetaOutput *old_output,
|
||||
GError **error);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user