From 9ea1b7a4b66fddfab9e65e243b72d18371f8d9a5 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 17 Jan 2014 08:25:26 -0300 Subject: [media] v4l2-ctrls: compare values only once When setting a control the control's new value is compared to the current value twice: once by new_to_cur(), once by cluster_changed(). Not a big deal when dealing with simple values, but it can be a problem when dealing with compound types or arrays. So fix this: cluster_changed() sets the has_changed flag, which is used by new_to_cur() instead of having to do another compare. Signed-off-by: Hans Verkuil Reviewed-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-ctrls.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index e7e0beab7048..1b4d37ce4afe 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -1424,8 +1424,11 @@ static void new_to_cur(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 ch_flags) if (ctrl == NULL) return; - changed = !ctrl->type_ops->equal(ctrl, ctrl->p_cur, ctrl->p_new); - ptr_to_ptr(ctrl, ctrl->p_new, ctrl->p_cur); + + /* has_changed is set by cluster_changed */ + changed = ctrl->has_changed; + if (changed) + ptr_to_ptr(ctrl, ctrl->p_new, ctrl->p_cur); if (ch_flags & V4L2_EVENT_CTRL_CH_FLAGS) { /* Note: CH_FLAGS is only set for auto clusters. */ @@ -1462,17 +1465,19 @@ static void cur_to_new(struct v4l2_ctrl *ctrl) value that differs from the current value. */ static int cluster_changed(struct v4l2_ctrl *master) { - int diff = 0; + bool changed = false; int i; - for (i = 0; !diff && i < master->ncontrols; i++) { + for (i = 0; i < master->ncontrols; i++) { struct v4l2_ctrl *ctrl = master->cluster[i]; if (ctrl == NULL) continue; - diff = !ctrl->type_ops->equal(ctrl, ctrl->p_cur, ctrl->p_new); + ctrl->has_changed = !ctrl->type_ops->equal(ctrl, + ctrl->p_cur, ctrl->p_new); + changed |= ctrl->has_changed; } - return diff; + return changed; } /* Control range checking */ -- cgit v1.2.1