summaryrefslogtreecommitdiff
path: root/test/pipeline
diff options
context:
space:
mode:
authorDavid Plowman <david.plowman@raspberrypi.com>2021-02-10 17:58:30 +0000
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2021-02-11 19:14:39 +0200
commitdb55e09b42f87d9a7fde32afc4e0eee90b4c7690 (patch)
treeaaa92af273619220ec683a4a2bf546363ab85cac /test/pipeline
parente36a6f40433ce661610f34ed2db31e82e22c579d (diff)
ipa: raspberrypi: AWB: Fix race condition setting manual gains
Applying the manual_r_ and manual_b_ values is entirely removed from the asynchronous thread where their use constituted a race hazard. The main thread now deals with them entirely, involving the following changes. 1. SetManualGains() applies the new values directly to the "sync_results", meaning that Prepare() will jump to the new values immediately (which is a better behaviour). 2. Process() does not restart the asynchronous thread when manual gains are in force. 3. The asynchronous thread might be running when manual gains are set, so we ignore the results produced in this case. Signed-off-by: David Plowman <david.plowman@raspberrypi.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Naushir Patuck <naush@raspberrypi.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'test/pipeline')
0 files changed, 0 insertions, 0 deletions
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
 * Copyright (C) 2020, Google Inc.
 *
 * flags.h - Type-safe enum-based bitfields
 */

#pragma once

#include <type_traits>

namespace libcamera {

template<typename E>
class Flags
{
public:
	static_assert(std::is_enum<E>::value,
		      "Flags<> template parameter must be an enum");

	using Type = std::underlying_type_t<E>;

	constexpr Flags()
		: value_(0)
	{
	}

	constexpr Flags(E flag)
		: value_(static_cast<Type>(flag))
	{
	}

	constexpr Flags &operator&=(E flag)
	{
		value_ &= static_cast<Type>(flag);
		return *this;
	}

	constexpr Flags &operator&=(Flags other)
	{
		value_ &= other.value_;
		return *this;
	}

	constexpr Flags &operator|=(E flag)
	{
		value_ |= static_cast<Type>(flag);
		return *this;
	}

	constexpr Flags &operator|=(Flags other)
	{
		value_ |= other.value_;
		return *this;
	}

	constexpr Flags &operator^=(E flag)
	{
		value_ ^= static_cast<Type>(flag);
		return *this;
	}

	constexpr Flags &operator^=(Flags other)
	{
		value_ ^= other.value_;
		return *this;
	}

	constexpr bool operator==(E flag)
	{
		return value_ == static_cast<Type>(flag);
	}

	constexpr bool operator==(Flags other)
	{
		return value_ == static_cast<Type>(other);
	}

	constexpr bool operator!=(E flag)
	{
		return value_ != static_cast<Type>(flag);
	}

	constexpr bool operator!=(Flags other)
	{
		return value_ != static_cast<Type>(other);
	}

	constexpr explicit operator Type() const
	{
		return value_;
	}

	constexpr explicit operator bool() const
	{
		return !!value_;
	}

	constexpr Flags operator&(E flag) const
	{
		return Flags(static_cast<E>(value_ & static_cast<Type>(flag)));
	}

	constexpr Flags operator&(Flags other) const
	{
		return Flags(static_cast<E>(value_ & other.value_));
	}

	constexpr Flags operator|(E flag) const
	{
		return Flags(static_cast<E>(value_ | static_cast<Type>(flag)));
	}

	constexpr Flags operator|(Flags other) const
	{
		return Flags(static_cast<E>(value_ | other.value_));
	}

	constexpr Flags operator^(E flag) const
	{
		return Flags(static_cast<E>(value_ ^ static_cast<Type>(flag)));
	}

	constexpr Flags operator^(Flags other) const
	{
		return Flags(static_cast<E>(value_ ^ other.value_));
	}

	constexpr Flags operator~() const
	{
		return Flags(static_cast<E>(~value_));
	}

	constexpr bool operator!() const
	{
		return !value_;
	}

private:
	Type value_;
};

#ifndef __DOXYGEN__
template<typename E>
struct flags_enable_operators {
	static const bool enable = false;
};

template<typename E>
std::enable_if_t<flags_enable_operators<E>::enable, Flags<E>>
operator|(E lhs, E rhs)
{
	using type = std::underlying_type_t<E>;
	return Flags<E>(static_cast<E>(static_cast<type>(lhs) | static_cast<type>(rhs)));
}

template<typename E>
std::enable_if_t<flags_enable_operators<E>::enable, Flags<E>>
operator&(E lhs, E rhs)
{
	using type = std::underlying_type_t<E>;
	return Flags<E>(static_cast<E>(static_cast<type>(lhs) & static_cast<type>(rhs)));
}

template<typename E>
std::enable_if_t<flags_enable_operators<E>::enable, Flags<E>>
operator^(E lhs, E rhs)
{
	using type = std::underlying_type_t<E>;
	return Flags<E>(static_cast<E>(static_cast<type>(lhs) ^ static_cast<type>(rhs)));
}

template<typename E>
std::enable_if_t<flags_enable_operators<E>::enable, Flags<E>>
operator~(E rhs)
{
	using type = std::underlying_type_t<E>;
	return Flags<E>(static_cast<E>(~static_cast<type>(rhs)));
}

#define LIBCAMERA_FLAGS_ENABLE_OPERATORS(_enum)				\
template<>								\
struct flags_enable_operators<_enum> {					\
	static const bool enable = true;				\
};

#else /* __DOXYGEN__ */

#define LIBCAMERA_FLAGS_ENABLE_OPERATORS(_enum)

#endif /* __DOXYGEN__ */

} /* namespace libcamera */