context: add some comments

This commit is contained in:
Wim Taymans 2022-04-14 10:16:20 +02:00
parent 2268d1838b
commit b0dcfa886d

View file

@ -1084,6 +1084,24 @@ static bool rates_contains(uint32_t *rates, uint32_t n_rates, uint32_t rate)
return false;
}
/* here we evaluate the complete state of the graph.
*
* It roughly operates in 3 stages:
*
* 1. go over all drivers and collect the nodes that need to be scheduled with the
* driver. This include all nodes that have an active link with the driver or
* with a node already scheduled with the driver.
*
* 2. go over all nodes that are not assigned to a driver. The ones that require
* a driver are moved to some random active driver found in step 1.
*
* 3. go over all drivers again, collect the quantum/rate of all followers, select
* the desired final value and activate the followers and then the driver.
*
* A complete graph evaluation is performed for each change that is made to the
* graph, such as making/destroting links, adding/removing nodes, property changes such
* as quantum/rate changes or metadata changes.
*/
int pw_context_recalc_graph(struct pw_context *context, const char *reason)
{
struct impl *impl = SPA_CONTAINER_OF(context, struct impl, this);
@ -1253,9 +1271,14 @@ again:
if (lock_rate ||
(!force_rate &&
(n->info.state > PW_NODE_STATE_IDLE)))
/* when someone wants us to lock the rate of this driver or
* when the driver is busy and we don't need to force a rate,
* keep the current rate */
target_rate = current_rate;
else {
/* calculate desired rate */
/* Here we are allowed to change the rate of the driver.
* Start with the default rate. If the desired rate is
* allowed, switch to it */
target_rate = def_rate;
if (rate.denom != 0 && rate.num == 1) {
if (rates_contains(rates, n_rates, rate.denom))
@ -1264,6 +1287,7 @@ again:
}
if (target_rate != current_rate) {
/* we doing a rate switch */
pw_log_info("(%s-%u) state:%s new rate:%u->%u",
n->name, n->info.id,
pw_node_state_as_string(n->info.state),
@ -1277,6 +1301,8 @@ again:
if (n->info.state >= PW_NODE_STATE_IDLE)
suspend_driver(context, n);
}
/* we're setting the pending rate. This will become the new
* current rate in the next iteration of the graph. */
n->current_rate = SPA_FRACTION(1, target_rate);
n->current_pending = true;
current_rate = target_rate;
@ -1285,6 +1311,7 @@ again:
}
if (rate_quantum != 0 && current_rate != rate_quantum) {
/* the quantum values are scaled with the current rate */
def_quantum = def_quantum * current_rate / rate_quantum;
min_quantum = min_quantum * current_rate / rate_quantum;
max_quantum = max_quantum * current_rate / rate_quantum;
@ -1311,11 +1338,16 @@ again:
n->name, n->info.id,
n->current_quantum,
quantum);
/* this is the new pending quantum */
n->current_quantum = quantum;
n->current_pending = true;
}
if (n->info.state < PW_NODE_STATE_RUNNING && n->current_pending) {
/* the driver node is not actually running and we have a
* panding change. Apply the change to the position now so
* that we have the right values when we change the node
* states of the driver and followers to RUNNING below */
n->rt.position->clock.duration = n->current_quantum;
n->rt.position->clock.rate = n->current_rate;
n->current_pending = false;
@ -1324,6 +1356,7 @@ again:
pw_log_debug("%p: driving %p running:%d passive:%d quantum:%u '%s'",
context, n, running, n->passive, quantum, n->name);
/* first change the node states of the followers to the new target */
spa_list_for_each(s, &n->follower_list, follower_link) {
if (s == n)
continue;
@ -1331,6 +1364,7 @@ again:
context, s, s->active, s->name);
ensure_state(s, running);
}
/* now that all the followers are ready, start the driver */
ensure_state(n, running);
}
impl->recalc = false;