/* SPDX-License-Identifier: LGPL-2.1-or-later */

module libcamera;

/**
 * \file core_ipa_interface.h
 * \brief libcamera structs for IPAs
 */

/*
 * Things that can be defined here (and in other mojom files):
 * - consts
 * - enums
 * - structs
 *
 * Attributes:
 * - skipHeader - allowed only for structs and enums in core.mojom
 *   - Do not generate a C++ definition for the structure or enum
 *   - Any type used in a mojom interface definition must have a corresponding
 *     definition in a mojom file for the code generator to accept it, except
 *     for types solely used as map/array members for which a definition is not
 *     required
 *   - This attribute allows defining a symbol for the code generator that
 *     corresponds to a libcamera type without duplicating its definition in the
 *     generated C++ headers
 * - skipSerdes - structs only, and only in core.mojom
 *   - All types need a (de)serializer to be defined in order to be transported
 *     over IPC. The (de)serializer can be:
 *     - Manually implemented as a template specialization in
 *       ipa_data_serializer.cpp in the libcamera sources
 *     - Generated at build time for types defined in a mojom file
 *   - This attribute instructs the build system that a (de)serializer is
 *     available for the type and there's no need to generate one
 * - hasFd - struct fields or empty structs only
 *   - Designate that this field or empty struct contains a SharedFD
 * - scopedEnum - enum definitions
 *   - Designate that this enum should be an enum class, as opposed to a pure
 *     enum
 * - flags - struct fields or function parameters that are enums
 *   - Designate that this enum type E should be Flags<E> in the generated C++
 *     code
 *   - For example, if a struct field is defined as `[flags] ErrorFlag f;`
 *     (where ErrorFlag is defined as an enum elsewhere in mojom), then the
 *     generated code for this field will be `Flags<ErrorFlag> f`
 *
 * Rules:
 * - If the type is defined in a libcamera C++ header *and* a (de)serializer is
 *   available then the type shall be declared as empty with both attributes
 *   associated and specified as: [skipHeader, skipSerdes]
 *   - Example: [skipHeader, skipSerdes] ControlList {};
 * - If the type is defined in libcamera but no (de)serializer is available
 *   then the type definition in the core.mojom file should have the
 *   [skipHeader] attribute only
 *   - A (de)serializer will be generated for the type
 *   - enums that are defined in a libcamera C++ header also fall in this
 *     category
 * - If a type definition has [skipHeader], then the header where the type is
 *   defined must be included in ipa_interface.h
 * - Types that are solely used as array/map members do not require a mojom
 *   definition if one exists in libcamera
 * - Nested types (e.g. FrameBuffer::Plane) cannot be defined in mojom
 *   - If used in mojom, the nested type shall be defined in a C++ header
 *     and a (de)serializer shall be provided
 *   - Nested types can only be used as array/map members
 *   - When using the type, the C++ namespace separator :: is replaced with a
 *     dot
 *   - In example, to use the FrameBuffer::Plane type in mojom:
 *     - Provide a definition of the FrameBuffer::Plane type in a C++ header
 *     - Include the header in ipa_interface.h
 *     - Provide a (de)serializer implementation ipa_data_serializer.cpp
 *     - In mojom, reference the type as FrameBuffer.Plane and only as map/array
 *       member
 * - [skipHeader] and [skipSerdes] only work here in core.mojom
 * - If a field in a struct has a SharedFD, but is not explicitly
 *   defined so in mojom, then the field must be marked with the [hasFd]
 *   attribute
 *
 * \todo Generate documentation from Doxygen comments in .mojom files
 * \todo Figure out how to keep the skipHeader structs in sync with their
 * C++ definitions, and the skipSerdes structs in sync with their
 * (de)serializers
 */
[skipSerdes, skipHeader] struct ControlInfoMap {};
[skipSerdes, skipHeader] struct ControlList {};
[skipSerdes, skipHeader] struct SharedFD {};

[skipHeader] struct Point {
	int32 x;
	int32 y;
};

[skipHeader] struct Size {
	uint32 width;
	uint32 height;
};

[skipHeader] struct SizeRange {
	Size min;
	Size max;
	uint32 hStep;
	uint32 vStep;
};

[skipHeader] struct Rectangle {
	int32 x;
	int32 y;
	uint32 width;
	uint32 height;
};

/**
 * \struct IPACameraSensorInfo
 * \brief Report the image sensor characteristics
 *
 * The structure reports image sensor characteristics used by IPA modules to
 * tune their algorithms based on the image sensor model currently in use and
 * its configuration.
 *
 * The reported information describes the sensor's intrinsics characteristics,
 * such as its pixel array size and the sensor model name, as well as
 * information relative to the currently configured mode, such as the produced
 * image size and the bit depth of the requested image format.
 *
 * Instances of this structure are meant to be assembled by the CameraSensor
 * class by inspecting the sensor static properties as well as information
 * relative to the current configuration.
 */

/**
 * \var IPACameraSensorInfo::model
 * \brief The image sensor model name
 *
 * The sensor model name is a free-formed string that uniquely identifies the
 * sensor model.
 */

/**
 * \var IPACameraSensorInfo::bitsPerPixel
 * \brief The number of bits per pixel of the image format produced by the
 * image sensor
 */

/**
 * \var IPACameraSensorInfo::cfaPattern
 * \brief The arrangement of colour filters on the image sensor
 *
 * This takes a value defined by properties::draft::ColorFilterArrangementEnum.
 * For non-Bayer colour sensors, the cfaPattern will be set to
 * properties::draft::ColorFilterArrangementEnum::RGB.
 *
 * \todo Make this variable optional once mojom supports it, instead of using
 * RGB for sensors that don't have a CFA.
 */

/**
 * \var IPACameraSensorInfo::activeAreaSize
 * \brief The size of the pixel array active area of the sensor
 */

/**
 * \var IPACameraSensorInfo::analogCrop
 * \brief The portion of the pixel array active area which is read-out and
 * processed
 *
 * The analog crop rectangle top-left corner is defined as the displacement
 * from the top-left corner of the pixel array active area. The rectangle
 * horizontal and vertical sizes define the portion of the pixel array which
 * is read-out and provided to the sensor's internal processing pipeline, before
 * any pixel sub-sampling method, such as pixel binning, skipping and averaging
 * take place.
 */

/**
 * \var IPACameraSensorInfo::outputSize
 * \brief The size of the images produced by the camera sensor
 *
 * The output image size defines the horizontal and vertical sizes of the images
 * produced by the image sensor. The output image size is defined as the end
 * result of the sensor's internal image processing pipeline stages, applied on
 * the pixel array portion defined by the analog crop rectangle. Each image
 * processing stage that performs pixel sub-sampling techniques, such as pixel
 * binning or skipping, or perform any additional digital scaling concur in the
 * definition of the output image size.
 */

/**
 * \var IPACameraSensorInfo::pixelRate
 * \brief The number of pixels produced in a second
 *
 * To obtain the read-out time in seconds of a full line:
 *
 * \verbatim
       lineDuration(s) = lineLength(pixels) / pixelRate(pixels per second)
   \endverbatim
 */

/**
 * \var IPACameraSensorInfo::minLineLength
 * \brief The minimum line length in pixels
 *
 * The minimum allowable line length in pixel clock periods, including blanking.
 */

/**
 * \var IPACameraSensorInfo::maxLineLength
 * \brief The maximum line length in pixels
 *
 * The maximum allowable line length in pixel clock periods, including blanking.
 */

/**
 * \var IPACameraSensorInfo::minFrameLength
 * \brief The minimum allowable frame length in units of lines
 *
 * The sensor frame length comprises of active output lines and blanking lines
 * in a frame. The minimum frame length value dictates the minimum allowable
 * frame duration of the sensor mode.
 *
 * To obtain the minimum frame duration:
 *
 * \verbatim
       frameDuration(s) = minFrameLength(lines) * minLineLength(pixels) / pixelRate(pixels per second)
   \endverbatim
 */

/**
 * \var IPACameraSensorInfo::maxFrameLength
 * \brief The maximum allowable frame length in units of lines
 *
 * The sensor frame length comprises of active output lines and blanking lines
 * in a frame. The maximum frame length value dictates the maximum allowable
 * frame duration of the sensor mode.
 *
 * To obtain the maximum frame duration:
 *
 * \verbatim
       frameDuration(s) = maxFrameLength(lines) * maxLineLength(pixels) / pixelRate(pixels per second)
   \endverbatim
 */
struct IPACameraSensorInfo {
	string model;

	uint32 bitsPerPixel;
	uint32 cfaPattern;

	Size activeAreaSize;
	Rectangle analogCrop;
	Size outputSize;

	uint64 pixelRate;

	uint32 minLineLength;
	uint32 maxLineLength;

	uint32 minFrameLength;
	uint32 maxFrameLength;
};

/**
 * \struct IPABuffer
 * \brief Buffer information for the IPA interface
 *
 * The IPABuffer structure associates buffer memory with a unique ID. It is
 * used to map buffers to the IPA with IPAInterface::mapBuffers(), after which
 * buffers will be identified by their ID in the IPA interface.
 */

/**
 * \var IPABuffer::id
 * \brief The buffer unique ID
 *
 * Buffers mapped to the IPA are identified by numerical unique IDs. The IDs
 * are chosen by the pipeline handler to fulfil the following constraints:
 *
 * - IDs shall be positive integers different than zero
 * - IDs shall be unique among all mapped buffers
 *
 * When buffers are unmapped with IPAInterface::unmapBuffers() their IDs are
 * freed and may be reused for new buffer mappings.
 */

/**
 * \var IPABuffer::planes
 * \brief The buffer planes description
 *
 * Stores the dmabuf handle and length for each plane of the buffer.
 */
struct IPABuffer {
	uint32 id;
	[hasFd] array<FrameBuffer.Plane> planes;
};

/**
 * \struct IPASettings
 * \brief IPA interface initialization settings
 *
 * The IPASettings structure stores data passed to the IPAInterface::init()
 * function. The data contains settings that don't depend on a particular camera
 * or pipeline configuration and are valid for the whole life time of the IPA
 * interface.
 */

/**
 * \var IPASettings::configurationFile
 * \brief The name of the IPA configuration file
 *
 * This field may be an empty string if the IPA doesn't require a configuration
 * file.
 */

/**
 * \var IPASettings::sensorModel
 * \brief The sensor model name
 *
 * Provides the sensor model name to the IPA.
 */
struct IPASettings {
	string configurationFile;
	string sensorModel;
};

/**
 * \struct IPAStream
 * \brief Stream configuration for the IPA interface
 *
 * The IPAStream structure stores stream configuration parameters needed by the
 * IPAInterface::configure() function. It mirrors the StreamConfiguration class
 * that is not suitable for this purpose due to not being serializable.
 */

/**
 * \var IPAStream::pixelFormat
 * \brief The stream pixel format
 */

/**
 * \var IPAStream::size
 * \brief The stream size in pixels
 */
struct IPAStream {
	uint32 pixelFormat;
	Size size;
};
