From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
Subject: Re: [PATCH 07/19] drm/atomic: Fix atomic helpers to use the new iterator macros.
Date: Thu, 3 Nov 2016 18:22:05 +0200 [thread overview]
Message-ID: <20161103162205.GB4617@intel.com> (raw)
In-Reply-To: <1476707838-25253-8-git-send-email-maarten.lankhorst@linux.intel.com>
On Mon, Oct 17, 2016 at 02:37:06PM +0200, Maarten Lankhorst wrote:
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
> drivers/gpu/drm/drm_atomic_helper.c | 302 +++++++++++++++++++-----------------
> 1 file changed, 157 insertions(+), 145 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index fcb6e5b55217..c8aba493fc17 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -103,7 +103,7 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
> * part of the state. If the same encoder is assigned to multiple
> * connectors bail out.
> */
> - for_each_connector_in_state(state, connector, conn_state, i) {
> + for_each_new_connector_in_state(state, connector, conn_state, i) {
> const struct drm_connector_helper_funcs *funcs = connector->helper_private;
> struct drm_encoder *new_encoder;
>
> @@ -238,22 +238,22 @@ steal_encoder(struct drm_atomic_state *state,
> {
> struct drm_crtc_state *crtc_state;
> struct drm_connector *connector;
> - struct drm_connector_state *connector_state;
> + struct drm_connector_state *old_connector_state, *new_connector_state;
> int i;
>
> - for_each_connector_in_state(state, connector, connector_state, i) {
> + for_each_oldnew_connector_in_state(state, connector, old_connector_state, new_connector_state, i) {
> struct drm_crtc *encoder_crtc;
>
> - if (connector_state->best_encoder != encoder)
> + if (new_connector_state->best_encoder != encoder)
> continue;
>
> - encoder_crtc = connector->state->crtc;
> + encoder_crtc = old_connector_state->crtc;
>
> DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], stealing it\n",
> encoder->base.id, encoder->name,
> encoder_crtc->base.id, encoder_crtc->name);
>
> - set_best_encoder(state, connector_state, NULL);
> + set_best_encoder(state, new_connector_state, NULL);
>
> crtc_state = drm_atomic_get_existing_crtc_state(state, encoder_crtc);
> crtc_state->connectors_changed = true;
> @@ -265,7 +265,8 @@ steal_encoder(struct drm_atomic_state *state,
> static int
> update_connector_routing(struct drm_atomic_state *state,
> struct drm_connector *connector,
> - struct drm_connector_state *connector_state)
> + struct drm_connector_state *old_connector_state,
> + struct drm_connector_state *new_connector_state)
> {
> const struct drm_connector_helper_funcs *funcs;
> struct drm_encoder *new_encoder;
> @@ -275,24 +276,24 @@ update_connector_routing(struct drm_atomic_state *state,
> connector->base.id,
> connector->name);
>
> - if (connector->state->crtc != connector_state->crtc) {
> - if (connector->state->crtc) {
> - crtc_state = drm_atomic_get_existing_crtc_state(state, connector->state->crtc);
> + if (old_connector_state->crtc != new_connector_state->crtc) {
> + if (old_connector_state->crtc) {
> + crtc_state = drm_atomic_get_existing_crtc_state(state, old_connector_state->crtc);
> crtc_state->connectors_changed = true;
> }
>
> - if (connector_state->crtc) {
> - crtc_state = drm_atomic_get_existing_crtc_state(state, connector_state->crtc);
> + if (new_connector_state->crtc) {
> + crtc_state = drm_atomic_get_existing_crtc_state(state, new_connector_state->crtc);
> crtc_state->connectors_changed = true;
> }
> }
>
> - if (!connector_state->crtc) {
> + if (!new_connector_state->crtc) {
> DRM_DEBUG_ATOMIC("Disabling [CONNECTOR:%d:%s]\n",
> connector->base.id,
> connector->name);
>
> - set_best_encoder(state, connector_state, NULL);
> + set_best_encoder(state, new_connector_state, NULL);
>
> return 0;
> }
> @@ -301,7 +302,7 @@ update_connector_routing(struct drm_atomic_state *state,
>
> if (funcs->atomic_best_encoder)
> new_encoder = funcs->atomic_best_encoder(connector,
> - connector_state);
> + new_connector_state);
> else if (funcs->best_encoder)
> new_encoder = funcs->best_encoder(connector);
> else
> @@ -314,33 +315,33 @@ update_connector_routing(struct drm_atomic_state *state,
> return -EINVAL;
> }
>
> - if (!drm_encoder_crtc_ok(new_encoder, connector_state->crtc)) {
> + if (!drm_encoder_crtc_ok(new_encoder, new_connector_state->crtc)) {
> DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] incompatible with [CRTC:%d]\n",
> new_encoder->base.id,
> new_encoder->name,
> - connector_state->crtc->base.id);
> + new_connector_state->crtc->base.id);
> return -EINVAL;
> }
>
> - if (new_encoder == connector_state->best_encoder) {
> - set_best_encoder(state, connector_state, new_encoder);
> + if (new_encoder == new_connector_state->best_encoder) {
> + set_best_encoder(state, new_connector_state, new_encoder);
>
> DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] keeps [ENCODER:%d:%s], now on [CRTC:%d:%s]\n",
> connector->base.id,
> connector->name,
> new_encoder->base.id,
> new_encoder->name,
> - connector_state->crtc->base.id,
> - connector_state->crtc->name);
> + new_connector_state->crtc->base.id,
> + new_connector_state->crtc->name);
>
> return 0;
> }
>
> steal_encoder(state, new_encoder);
>
> - set_best_encoder(state, connector_state, new_encoder);
> + set_best_encoder(state, new_connector_state, new_encoder);
>
> - crtc_state = drm_atomic_get_existing_crtc_state(state, connector_state->crtc);
> + crtc_state = drm_atomic_get_existing_crtc_state(state, new_connector_state->crtc);
> crtc_state->connectors_changed = true;
>
> DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] using [ENCODER:%d:%s] on [CRTC:%d:%s]\n",
> @@ -348,8 +349,8 @@ update_connector_routing(struct drm_atomic_state *state,
> connector->name,
> new_encoder->base.id,
> new_encoder->name,
> - connector_state->crtc->base.id,
> - connector_state->crtc->name);
> + new_connector_state->crtc->base.id,
> + new_connector_state->crtc->name);
>
> return 0;
> }
> @@ -364,7 +365,7 @@ mode_fixup(struct drm_atomic_state *state)
> int i;
> bool ret;
>
> - for_each_crtc_in_state(state, crtc, crtc_state, i) {
> + for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
> if (!crtc_state->mode_changed &&
> !crtc_state->connectors_changed)
> continue;
> @@ -372,7 +373,7 @@ mode_fixup(struct drm_atomic_state *state)
> drm_mode_copy(&crtc_state->adjusted_mode, &crtc_state->mode);
> }
>
> - for_each_connector_in_state(state, connector, conn_state, i) {
> + for_each_new_connector_in_state(state, connector, conn_state, i) {
> const struct drm_encoder_helper_funcs *funcs;
> struct drm_encoder *encoder;
>
> @@ -417,7 +418,7 @@ mode_fixup(struct drm_atomic_state *state)
> }
> }
>
> - for_each_crtc_in_state(state, crtc, crtc_state, i) {
> + for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
> const struct drm_crtc_helper_funcs *funcs;
>
> if (!crtc_state->enable)
> @@ -476,19 +477,19 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
> struct drm_atomic_state *state)
> {
> struct drm_crtc *crtc;
> - struct drm_crtc_state *crtc_state;
> + struct drm_crtc_state *old_crtc_state, *new_crtc_state;
> struct drm_connector *connector;
> - struct drm_connector_state *connector_state;
> + struct drm_connector_state *old_connector_state, *new_connector_state;
> int i, ret;
>
> - for_each_crtc_in_state(state, crtc, crtc_state, i) {
> - if (!drm_mode_equal(&crtc->state->mode, &crtc_state->mode)) {
> + for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
> + if (!drm_mode_equal(&old_crtc_state->mode, &new_crtc_state->mode)) {
> DRM_DEBUG_ATOMIC("[CRTC:%d:%s] mode changed\n",
> crtc->base.id, crtc->name);
> - crtc_state->mode_changed = true;
> + new_crtc_state->mode_changed = true;
> }
>
> - if (crtc->state->enable != crtc_state->enable) {
> + if (old_crtc_state->enable != new_crtc_state->enable) {
> DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enable changed\n",
> crtc->base.id, crtc->name);
>
> @@ -500,8 +501,8 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
> * The other way around is true as well. enable != 0
> * iff connectors are attached and a mode is set.
> */
> - crtc_state->mode_changed = true;
> - crtc_state->connectors_changed = true;
> + new_crtc_state->mode_changed = true;
> + new_crtc_state->connectors_changed = true;
> }
> }
>
> @@ -509,14 +510,15 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
> if (ret)
> return ret;
>
> - for_each_connector_in_state(state, connector, connector_state, i) {
> + for_each_oldnew_connector_in_state(state, connector, old_connector_state, new_connector_state, i) {
> /*
> * This only sets crtc->connectors_changed for routing changes,
> * drivers must set crtc->connectors_changed themselves when
> * connector properties need to be updated.
> */
> ret = update_connector_routing(state, connector,
> - connector_state);
> + old_connector_state,
> + new_connector_state);
> if (ret)
> return ret;
> }
> @@ -527,28 +529,28 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
> * configuration. This must be done before calling mode_fixup in case a
> * crtc only changed its mode but has the same set of connectors.
> */
> - for_each_crtc_in_state(state, crtc, crtc_state, i) {
> + for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
> bool has_connectors =
> - !!crtc_state->connector_mask;
> + !!new_crtc_state->connector_mask;
>
> /*
> * We must set ->active_changed after walking connectors for
> * otherwise an update that only changes active would result in
> * a full modeset because update_connector_routing force that.
> */
> - if (crtc->state->active != crtc_state->active) {
> + if (old_crtc_state->active != new_crtc_state->active) {
> DRM_DEBUG_ATOMIC("[CRTC:%d:%s] active changed\n",
> crtc->base.id, crtc->name);
> - crtc_state->active_changed = true;
> + new_crtc_state->active_changed = true;
> }
>
> - if (!drm_atomic_crtc_needs_modeset(crtc_state))
> + if (!drm_atomic_crtc_needs_modeset(new_crtc_state))
> continue;
>
> DRM_DEBUG_ATOMIC("[CRTC:%d:%s] needs all connectors, enable: %c, active: %c\n",
> crtc->base.id, crtc->name,
> - crtc_state->enable ? 'y' : 'n',
> - crtc_state->active ? 'y' : 'n');
> + new_crtc_state->enable ? 'y' : 'n',
> + new_crtc_state->active ? 'y' : 'n');
>
> ret = drm_atomic_add_affected_connectors(state, crtc);
> if (ret != 0)
> @@ -558,7 +560,7 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
> if (ret != 0)
> return ret;
>
> - if (crtc_state->enable != has_connectors) {
> + if (new_crtc_state->enable != has_connectors) {
> DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enabled/connectors mismatch\n",
> crtc->base.id, crtc->name);
>
> @@ -599,7 +601,7 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
> if (ret)
> return ret;
>
> - for_each_plane_in_state(state, plane, plane_state, i) {
> + for_each_new_plane_in_state(state, plane, plane_state, i) {
> const struct drm_plane_helper_funcs *funcs;
>
> funcs = plane->helper_private;
> @@ -617,7 +619,7 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
> }
> }
>
> - for_each_crtc_in_state(state, crtc, crtc_state, i) {
> + for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
> const struct drm_crtc_helper_funcs *funcs;
>
> funcs = crtc->helper_private;
Up to here everything runs in the check phase, so the straightforwared
s/state/new_state/ and s/foo->state/old_state/ looks correct.
> @@ -678,12 +680,12 @@ static void
> disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
> {
> struct drm_connector *connector;
> - struct drm_connector_state *old_conn_state;
> + struct drm_connector_state *old_conn_state, *new_conn_state;
> struct drm_crtc *crtc;
> - struct drm_crtc_state *old_crtc_state;
> + struct drm_crtc_state *old_crtc_state, *new_crtc_state;
> int i;
>
> - for_each_connector_in_state(old_state, connector, old_conn_state, i) {
> + for_each_oldnew_connector_in_state(old_state, connector, old_conn_state, new_conn_state, i) {
> const struct drm_encoder_helper_funcs *funcs;
> struct drm_encoder *encoder;
>
> @@ -720,7 +722,7 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
>
> /* Right function depends upon target state. */
> if (funcs) {
> - if (connector->state->crtc && funcs->prepare)
> + if (new_conn_state->crtc && funcs->prepare)
> funcs->prepare(encoder);
> else if (funcs->disable)
> funcs->disable(encoder);
> @@ -731,11 +733,11 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
> drm_bridge_post_disable(encoder->bridge);
> }
>
> - for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
> + for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
> const struct drm_crtc_helper_funcs *funcs;
>
> /* Shut down everything that needs a full modeset. */
> - if (!drm_atomic_crtc_needs_modeset(crtc->state))
> + if (!drm_atomic_crtc_needs_modeset(new_crtc_state))
> continue;
>
> if (!old_crtc_state->active)
> @@ -748,7 +750,7 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
>
>
> /* Right function depends upon target state. */
> - if (crtc->state->enable && funcs->prepare)
> + if (new_crtc_state->enable && funcs->prepare)
> funcs->prepare(crtc);
> else if (funcs->atomic_disable)
> funcs->atomic_disable(crtc, old_crtc_state);
And this sucker is executed after we've swapped the state, so we need to
do the s/foo->state/new_state/ replacement. Looks correct to me.
Not sure how worried I should be that we might forget some foo->state
dereference somewhere. Should we try rename that pointer to something else
to make sure we've caught everything?
> @@ -777,13 +779,13 @@ drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev,
> struct drm_atomic_state *old_state)
> {
> struct drm_connector *connector;
> - struct drm_connector_state *old_conn_state;
> + struct drm_connector_state *old_conn_state, *new_conn_state;
> struct drm_crtc *crtc;
> - struct drm_crtc_state *old_crtc_state;
> + struct drm_crtc_state *crtc_state;
> int i;
>
> /* clear out existing links and update dpms */
> - for_each_connector_in_state(old_state, connector, old_conn_state, i) {
> + for_each_oldnew_connector_in_state(old_state, connector, old_conn_state, new_conn_state, i) {
> if (connector->encoder) {
> WARN_ON(!connector->encoder->crtc);
>
> @@ -791,7 +793,7 @@ drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev,
> connector->encoder = NULL;
> }
>
> - crtc = connector->state->crtc;
> + crtc = new_conn_state->crtc;
> if ((!crtc && old_conn_state->crtc) ||
> (crtc && drm_atomic_crtc_needs_modeset(crtc->state))) {
^^^^^^^^^^^^
Like this guy here. That should be new_crtc_state, no?
> struct drm_property *dpms_prop =
> @@ -808,23 +810,23 @@ drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev,
> }
>
> /* set new links */
> - for_each_connector_in_state(old_state, connector, old_conn_state, i) {
> - if (!connector->state->crtc)
> + for_each_new_connector_in_state(old_state, connector, new_conn_state, i) {
> + if (!new_conn_state->crtc)
> continue;
>
> - if (WARN_ON(!connector->state->best_encoder))
> + if (WARN_ON(!new_conn_state->best_encoder))
> continue;
>
> - connector->encoder = connector->state->best_encoder;
> - connector->encoder->crtc = connector->state->crtc;
> + connector->encoder = new_conn_state->best_encoder;
> + connector->encoder->crtc = new_conn_state->crtc;
> }
>
> /* set legacy state in the crtc structure */
> - for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
> + for_each_new_crtc_in_state(old_state, crtc, crtc_state, i) {
> struct drm_plane *primary = crtc->primary;
>
> - crtc->mode = crtc->state->mode;
> - crtc->enabled = crtc->state->enable;
> + crtc->mode = crtc_state->mode;
> + crtc->enabled = crtc_state->enable;
>
> if (drm_atomic_get_existing_plane_state(old_state, primary) &&
> primary->state->crtc == crtc) {
^^^^^^^^^^^^^^
new_plane_state or something?
> @@ -832,9 +834,9 @@ drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev,
> crtc->y = primary->state->src_y >> 16;
> }
>
> - if (crtc->state->enable)
> + if (crtc_state->enable)
> drm_calc_timestamping_constants(crtc,
> - &crtc->state->adjusted_mode);
> + &crtc_state->adjusted_mode);
> }
> }
> EXPORT_SYMBOL(drm_atomic_helper_update_legacy_modeset_state);
> @@ -843,20 +845,20 @@ static void
> crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state)
> {
> struct drm_crtc *crtc;
> - struct drm_crtc_state *old_crtc_state;
> + struct drm_crtc_state *crtc_state;
> struct drm_connector *connector;
> - struct drm_connector_state *old_conn_state;
> + struct drm_connector_state *conn_state;
> int i;
>
> - for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
> + for_each_new_crtc_in_state(old_state, crtc, crtc_state, i) {
> const struct drm_crtc_helper_funcs *funcs;
>
> - if (!crtc->state->mode_changed)
> + if (!crtc_state->mode_changed)
> continue;
>
> funcs = crtc->helper_private;
>
> - if (crtc->state->enable && funcs->mode_set_nofb) {
> + if (crtc_state->enable && funcs->mode_set_nofb) {
> DRM_DEBUG_ATOMIC("modeset on [CRTC:%d:%s]\n",
> crtc->base.id, crtc->name);
>
> @@ -864,18 +866,18 @@ crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state)
> }
> }
>
> - for_each_connector_in_state(old_state, connector, old_conn_state, i) {
> + for_each_new_connector_in_state(old_state, connector, conn_state, i) {
> const struct drm_encoder_helper_funcs *funcs;
> struct drm_crtc_state *new_crtc_state;
> struct drm_encoder *encoder;
> struct drm_display_mode *mode, *adjusted_mode;
>
> - if (!connector->state->best_encoder)
> + if (!conn_state->best_encoder)
> continue;
>
> - encoder = connector->state->best_encoder;
> + encoder = conn_state->best_encoder;
> funcs = encoder->helper_private;
> - new_crtc_state = connector->state->crtc->state;
> + new_crtc_state = conn_state->crtc->state;
> mode = &new_crtc_state->mode;
> adjusted_mode = &new_crtc_state->adjusted_mode;
>
> @@ -891,7 +893,7 @@ crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state)
> */
> if (funcs && funcs->atomic_mode_set) {
> funcs->atomic_mode_set(encoder, new_crtc_state,
> - connector->state);
> + conn_state);
> } else if (funcs && funcs->mode_set) {
> funcs->mode_set(encoder, mode, adjusted_mode);
> }
> @@ -943,24 +945,24 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
> struct drm_atomic_state *old_state)
> {
> struct drm_crtc *crtc;
> - struct drm_crtc_state *old_crtc_state;
> + struct drm_crtc_state *crtc_state;
> struct drm_connector *connector;
> - struct drm_connector_state *old_conn_state;
> + struct drm_connector_state *conn_state;
> int i;
>
> - for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
> + for_each_new_crtc_in_state(old_state, crtc, crtc_state, i) {
> const struct drm_crtc_helper_funcs *funcs;
>
> /* Need to filter out CRTCs where only planes change. */
> - if (!drm_atomic_crtc_needs_modeset(crtc->state))
> + if (!drm_atomic_crtc_needs_modeset(crtc_state))
> continue;
>
> - if (!crtc->state->active)
> + if (!crtc_state->active)
> continue;
>
> funcs = crtc->helper_private;
>
> - if (crtc->state->enable) {
> + if (crtc_state->enable) {
> DRM_DEBUG_ATOMIC("enabling [CRTC:%d:%s]\n",
> crtc->base.id, crtc->name);
>
> @@ -971,18 +973,18 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
> }
> }
>
> - for_each_connector_in_state(old_state, connector, old_conn_state, i) {
> + for_each_new_connector_in_state(old_state, connector, conn_state, i) {
> const struct drm_encoder_helper_funcs *funcs;
> struct drm_encoder *encoder;
>
> - if (!connector->state->best_encoder)
> + if (!conn_state->best_encoder)
> continue;
>
> - if (!connector->state->crtc->state->active ||
> - !drm_atomic_crtc_needs_modeset(connector->state->crtc->state))
> + if (!conn_state->crtc->state->active ||
> + !drm_atomic_crtc_needs_modeset(conn_state->crtc->state))
More foo->state stuff remaining
> continue;
>
> - encoder = connector->state->best_encoder;
> + encoder = conn_state->best_encoder;
> funcs = encoder->helper_private;
>
> DRM_DEBUG_ATOMIC("enabling [ENCODER:%d:%s]\n",
> @@ -1027,10 +1029,7 @@ int drm_atomic_helper_wait_for_fences(struct drm_device *dev,
> struct drm_plane_state *plane_state;
> int i, ret;
>
> - for_each_plane_in_state(state, plane, plane_state, i) {
> - if (!pre_swap)
> - plane_state = plane->state;
> -
> + for_each_new_plane_in_state(state, plane, plane_state, i) {
Nice. Can we kill the pre_swap flag now? Hmm, no, we pass it to
dma_fence_wait() to indicate interruptible vs. not. Maybe we can rename
it to convey its only remaining function better?
> if (!plane_state->fence)
> continue;
>
> @@ -1072,15 +1071,15 @@ bool drm_atomic_helper_framebuffer_changed(struct drm_device *dev,
> struct drm_crtc *crtc)
> {
> struct drm_plane *plane;
> - struct drm_plane_state *old_plane_state;
> + struct drm_plane_state *old_plane_state, *new_plane_state;
> int i;
>
> - for_each_plane_in_state(old_state, plane, old_plane_state, i) {
> - if (plane->state->crtc != crtc &&
> + for_each_oldnew_plane_in_state(old_state, plane, old_plane_state, new_plane_state, i) {
> + if (new_plane_state->crtc != crtc &&
> old_plane_state->crtc != crtc)
> continue;
>
> - if (plane->state->fb != old_plane_state->fb)
> + if (new_plane_state->fb != old_plane_state->fb)
> return true;
> }
This thing was totally broken, but I guess now it actually should
work regardless of when we call it. Cool.
I was actually wonder if we manage to plumb the old+new state everywhere
maybe we could kill off some of the need_whatever flags? Not quite sure.
>
> @@ -1104,21 +1103,21 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
> struct drm_atomic_state *old_state)
> {
> struct drm_crtc *crtc;
> - struct drm_crtc_state *old_crtc_state;
> + struct drm_crtc_state *old_crtc_state, *new_crtc_state;
> int i, ret;
>
> - for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
> + /* Legacy cursor ioctls are completely unsynced, and userspace
> + * relies on that (by doing tons of cursor updates). */
> + if (old_state->legacy_cursor_update)
> + return;
> +
We seem to have a change of behaviour here. Should be in a separate
patch if we actually want it.
> + for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
> /* No one cares about the old state, so abuse it for tracking
> * and store whether we hold a vblank reference (and should do a
> * vblank wait) in the ->enable boolean. */
> old_crtc_state->enable = false;
>
> - if (!crtc->state->enable)
> - continue;
> -
> - /* Legacy cursor ioctls are completely unsynced, and userspace
> - * relies on that (by doing tons of cursor updates). */
> - if (old_state->legacy_cursor_update)
> + if (!new_crtc_state->enable)
> continue;
>
> if (!drm_atomic_helper_framebuffer_changed(dev,
> @@ -1133,7 +1132,7 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
> old_crtc_state->last_vblank_count = drm_crtc_vblank_count(crtc);
> }
>
> - for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
> + for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i) {
> if (!old_crtc_state->enable)
> continue;
>
I think pretty much evething up to this point (from the last checkpoint)
is executed after swapping the state, with
drm_atomic_helper_framebuffer_changed() being the oddball that might be
called from anywhere.
> @@ -1432,11 +1431,11 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
> bool nonblock)
> {
> struct drm_crtc *crtc;
> - struct drm_crtc_state *crtc_state;
> + struct drm_crtc_state *old_crtc_state, *crtc_state;
> struct drm_crtc_commit *commit;
> int i, ret;
>
> - for_each_crtc_in_state(state, crtc, crtc_state, i) {
> + for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, crtc_state, i) {
> commit = kzalloc(sizeof(*commit), GFP_KERNEL);
> if (!commit)
> return -ENOMEM;
> @@ -1457,7 +1456,7 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
> /* Drivers only send out events when at least either current or
> * new CRTC state is active. Complete right away if everything
> * stays off. */
> - if (!crtc->state->active && !crtc_state->active) {
> + if (!old_crtc_state->active && !crtc_state->active) {
> complete_all(&commit->flip_done);
> continue;
> }
This guy is pre state swap. Looks correct.
> @@ -1521,7 +1520,7 @@ void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *state)
> int i;
> long ret;
>
> - for_each_crtc_in_state(state, crtc, crtc_state, i) {
> + for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
This is post state swap, but we don't actually use the new or the old
state here, so this looks fine.
> spin_lock(&crtc->commit_lock);
> commit = preceeding_commit(crtc);
> if (commit)
> @@ -1572,13 +1571,13 @@ void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *state)
> struct drm_crtc_commit *commit;
> int i;
>
> - for_each_crtc_in_state(state, crtc, crtc_state, i) {
> + for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
> commit = state->crtcs[i].commit;
> if (!commit)
> continue;
>
> /* backend must have consumed any event by now */
> - WARN_ON(crtc->state->event);
> + WARN_ON(crtc_state->event);
Post swap. Looks correct.
> spin_lock(&crtc->commit_lock);
> complete_all(&commit->hw_done);
> spin_unlock(&crtc->commit_lock);
> @@ -1605,7 +1604,7 @@ void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *state)
> int i;
> long ret;
>
> - for_each_crtc_in_state(state, crtc, crtc_state, i) {
> + for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
Post swap. State not used, so fine.
> commit = state->crtcs[i].commit;
> if (WARN_ON(!commit))
> continue;
> @@ -1658,7 +1657,7 @@ int drm_atomic_helper_prepare_planes(struct drm_device *dev,
> struct drm_plane_state *plane_state;
> int ret, i, j;
>
> - for_each_plane_in_state(state, plane, plane_state, i) {
> + for_each_new_plane_in_state(state, plane, plane_state, i) {
> const struct drm_plane_helper_funcs *funcs;
>
> funcs = plane->helper_private;
> @@ -1676,7 +1675,7 @@ int drm_atomic_helper_prepare_planes(struct drm_device *dev,
> return 0;
>
> fail:
> - for_each_plane_in_state(state, plane, plane_state, j) {
> + for_each_new_plane_in_state(state, plane, plane_state, j) {
Pre swap stuff. Fine.
> const struct drm_plane_helper_funcs *funcs;
>
> if (j >= i)
> @@ -1746,14 +1745,14 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev,
> uint32_t flags)
> {
> struct drm_crtc *crtc;
> - struct drm_crtc_state *old_crtc_state;
> + struct drm_crtc_state *old_crtc_state, *new_crtc_state;
> struct drm_plane *plane;
> - struct drm_plane_state *old_plane_state;
> + struct drm_plane_state *old_plane_state, *new_plane_state;
> int i;
> bool active_only = flags & DRM_PLANE_COMMIT_ACTIVE_ONLY;
> bool no_disable = flags & DRM_PLANE_COMMIT_NO_DISABLE_AFTER_MODESET;
>
> - for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
> + for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
> const struct drm_crtc_helper_funcs *funcs;
>
> funcs = crtc->helper_private;
> @@ -1761,13 +1760,13 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev,
> if (!funcs || !funcs->atomic_begin)
> continue;
>
> - if (active_only && !crtc->state->active)
> + if (active_only && !new_crtc_state->active)
> continue;
>
> funcs->atomic_begin(crtc, old_crtc_state);
> }
>
> - for_each_plane_in_state(old_state, plane, old_plane_state, i) {
> + for_each_oldnew_plane_in_state(old_state, plane, old_plane_state, new_plane_state, i) {
> const struct drm_plane_helper_funcs *funcs;
> bool disabling;
>
> @@ -1786,7 +1785,7 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev,
> * CRTC to avoid skipping planes being disabled on an
> * active CRTC.
> */
> - if (!disabling && !plane_crtc_active(plane->state))
> + if (!disabling && !plane_crtc_active(new_plane_state))
> continue;
> if (disabling && !plane_crtc_active(old_plane_state))
> continue;
> @@ -1805,12 +1804,12 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev,
> continue;
>
> funcs->atomic_disable(plane, old_plane_state);
> - } else if (plane->state->crtc || disabling) {
> + } else if (new_plane_state->crtc || disabling) {
> funcs->atomic_update(plane, old_plane_state);
> }
> }
>
> - for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
> + for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
> const struct drm_crtc_helper_funcs *funcs;
>
> funcs = crtc->helper_private;
> @@ -1818,7 +1817,7 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev,
> if (!funcs || !funcs->atomic_flush)
> continue;
>
> - if (active_only && !crtc->state->active)
> + if (active_only && !new_crtc_state->active)
> continue;
>
> funcs->atomic_flush(crtc, old_crtc_state);
> @@ -1945,12 +1944,19 @@ void drm_atomic_helper_cleanup_planes(struct drm_device *dev,
> struct drm_atomic_state *old_state)
> {
> struct drm_plane *plane;
> - struct drm_plane_state *plane_state;
> + struct drm_plane_state *plane_state, *new_plane_state;
> int i;
>
> - for_each_plane_in_state(old_state, plane, plane_state, i) {
> + for_each_oldnew_plane_in_state(old_state, plane, plane_state, new_plane_state, i) {
> const struct drm_plane_helper_funcs *funcs;
>
> + /*
> + * This might be called before swapping when commit is aborted,
> + * in which case we have to free the new state.
> + */
> + if (plane_state == plane->state)
> + plane_state = new_plane_state;
Oh dear. Can we make this nicer somehow? I can't actually see any use
like that currently. Am I blind?
I was wondering if we should add some kind of asserts to a bunch of
these functions to make sure they are called during the correct phase
of the operation. We could track the progress in the top level state I
guess.
> +
> if (!drm_atomic_helper_framebuffer_changed(dev, old_state, plane_state->crtc))
> continue;
>
> @@ -1998,15 +2004,15 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
> int i;
> long ret;
> struct drm_connector *connector;
> - struct drm_connector_state *conn_state;
> + struct drm_connector_state *old_conn_state, *new_conn_state;
> struct drm_crtc *crtc;
> - struct drm_crtc_state *crtc_state;
> + struct drm_crtc_state *old_crtc_state, *new_crtc_state;
> struct drm_plane *plane;
> - struct drm_plane_state *plane_state;
> + struct drm_plane_state *old_plane_state, *new_plane_state;
> struct drm_crtc_commit *commit;
>
> if (stall) {
> - for_each_crtc_in_state(state, crtc, crtc_state, i) {
> + for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
> spin_lock(&crtc->commit_lock);
> commit = list_first_entry_or_null(&crtc->commit_list,
> struct drm_crtc_commit, commit_entry);
> @@ -2026,16 +2032,20 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
> }
> }
>
> - for_each_connector_in_state(state, connector, conn_state, i) {
> - connector->state->state = state;
> - swap(state->connectors[i].state, connector->state);
> - connector->state->state = NULL;
> + for_each_oldnew_connector_in_state(state, connector, old_conn_state, new_conn_state, i) {
> + old_conn_state->state = state;
> + new_conn_state->state = NULL;
> +
> + state->connectors[i].state = old_conn_state;
> + connector->state = new_conn_state;
> }
>
> - for_each_crtc_in_state(state, crtc, crtc_state, i) {
> - crtc->state->state = state;
> - swap(state->crtcs[i].state, crtc->state);
> - crtc->state->state = NULL;
> + for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
> + old_crtc_state->state = state;
> + new_crtc_state->state = NULL;
> +
> + state->crtcs[i].state = old_crtc_state;
> + crtc->state = new_crtc_state;
>
> if (state->crtcs[i].commit) {
> spin_lock(&crtc->commit_lock);
> @@ -2047,10 +2057,12 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
> }
> }
>
> - for_each_plane_in_state(state, plane, plane_state, i) {
> - plane->state->state = state;
> - swap(state->planes[i].state, plane->state);
> - plane->state->state = NULL;
> + for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
> + old_plane_state->state = state;
> + new_plane_state->state = NULL;
> +
> + state->planes[i].state = old_plane_state;
> + plane->state = new_plane_state;
> }
> }
lgtm
> EXPORT_SYMBOL(drm_atomic_helper_swap_state);
> @@ -2248,7 +2260,7 @@ static int update_output_state(struct drm_atomic_state *state,
> if (ret)
> return ret;
>
> - for_each_connector_in_state(state, connector, conn_state, i) {
> + for_each_new_connector_in_state(state, connector, conn_state, i) {
> if (conn_state->crtc == set->crtc) {
> ret = drm_atomic_set_crtc_for_connector(conn_state,
> NULL);
> @@ -2270,7 +2282,7 @@ static int update_output_state(struct drm_atomic_state *state,
> return ret;
> }
>
> - for_each_crtc_in_state(state, crtc, crtc_state, i) {
> + for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
> /* Don't update ->enable for the CRTC in the set_config request,
> * since a mismatch would indicate a bug in the upper layers.
> * The actual modeset code later on will catch any
Building up the new state. Looks correct.
Phew! Apart from some of the lingering foo->state dereferences and the
change in behaviour for legacy cursors, and the slight oddballness in
the plane_cleanup() I didn't spot anything wrong.
This thing could use a commit message I think. Could at least lay out
the basic rules on the foo->state/foo_state vs. old_state/new_state
replacements. Might help someone understand it who doesn't know so much
about the current state swapping mechanism.
--
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2016-11-03 16:22 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-10-17 12:36 [PATCH 00/19] drm/atomic: Use less confusing iterator names Maarten Lankhorst
2016-10-17 12:37 ` [PATCH 01/19] drm/atomic: Add new iterators over all state Maarten Lankhorst
2016-11-01 13:09 ` [Intel-gfx] " Ville Syrjälä
2016-11-01 13:34 ` Maarten Lankhorst
2016-11-01 13:41 ` Ville Syrjälä
2016-11-02 8:28 ` Maarten Lankhorst
2016-11-03 15:11 ` [Intel-gfx] " Ville Syrjälä
2016-11-16 12:56 ` Maarten Lankhorst
2016-11-08 8:50 ` [Intel-gfx] " Daniel Vetter
2016-10-17 12:37 ` [PATCH 02/19] drm/atmel-hlcdc: Use new atomic iterator macros Maarten Lankhorst
2016-10-17 12:37 ` [PATCH 03/19] drm/exynos: " Maarten Lankhorst
2016-10-17 12:37 ` [PATCH 04/19] drm/blend: " Maarten Lankhorst
2016-11-03 15:26 ` Ville Syrjälä
2016-10-17 12:37 ` [PATCH 05/19] drm/atomic: Make add_affected_connectors look at crtc_state Maarten Lankhorst
2016-11-03 15:32 ` Ville Syrjälä
2016-11-08 8:51 ` [Intel-gfx] " Daniel Vetter
2016-10-17 12:37 ` [PATCH 06/19] drm/atomic: Use new atomic iterator macros Maarten Lankhorst
2016-11-03 15:35 ` [Intel-gfx] " Ville Syrjälä
2016-10-17 12:37 ` [PATCH 07/19] drm/atomic: Fix atomic helpers to use the new " Maarten Lankhorst
2016-11-03 16:22 ` Ville Syrjälä [this message]
2016-11-08 8:53 ` Daniel Vetter
2016-10-17 12:37 ` [PATCH 08/19] drm/vc4: Use new atomic " Maarten Lankhorst
2016-10-17 12:37 ` [PATCH 09/19] drm/rockchip: " Maarten Lankhorst
2016-10-17 12:37 ` [PATCH 10/19] drm/rcar-du: " Maarten Lankhorst
2016-10-17 12:37 ` [PATCH 11/19] drm/omap: " Maarten Lankhorst
2016-10-17 12:37 ` [PATCH 12/19] drm/msm: " Maarten Lankhorst
2016-11-03 16:37 ` [Intel-gfx] " Ville Syrjälä
2016-10-17 12:37 ` [PATCH 13/19] drm/imx: " Maarten Lankhorst
2016-10-17 12:37 ` [PATCH 14/19] drm/mediatek: " Maarten Lankhorst
2016-11-03 16:39 ` Ville Syrjälä
2016-10-17 12:37 ` [PATCH 15/19] drm/i915: Use new atomic iterator macros in ddi Maarten Lankhorst
2016-11-03 17:07 ` Ville Syrjälä
2016-10-17 12:37 ` [PATCH 16/19] drm/i915: Use new atomic iterator macros in fbc Maarten Lankhorst
2016-11-03 16:45 ` Ville Syrjälä
2016-11-03 17:45 ` Paulo Zanoni
2016-11-03 17:55 ` [Intel-gfx] " Ville Syrjälä
2016-11-03 17:59 ` Ville Syrjälä
2016-10-17 12:37 ` [PATCH 17/19] drm/i915: Use new atomic iterator macros in wm code Maarten Lankhorst
2016-11-03 16:49 ` [Intel-gfx] " Ville Syrjälä
2016-11-03 17:53 ` Paulo Zanoni
2016-10-17 12:37 ` [PATCH 18/19] drm/i915: Use new atomic iterator macros in display code Maarten Lankhorst
2016-11-03 17:04 ` [Intel-gfx] " Ville Syrjälä
2016-10-17 12:37 ` [PATCH 19/19] drm/atomic: Rename atomic oldnew iterator Maarten Lankhorst
2016-11-03 17:11 ` [Intel-gfx] " Ville Syrjälä
2016-10-17 13:25 ` ✗ Fi.CI.BAT: warning for drm/atomic: Use less confusing iterator names Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20161103162205.GB4617@intel.com \
--to=ville.syrjala@linux.intel.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=intel-gfx@lists.freedesktop.org \
--cc=maarten.lankhorst@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.