/*
 * Copyright (C) 2016 Samsung Electronics Co.Ltd
 * Authors:
 *	Marek Szyprowski <m.szyprowski@samsung.com>
 *
 * DRM core plane blending related functions
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that copyright
 * notice and this permission notice appear in supporting documentation, and
 * that the name of the copyright holders not be used in advertising or
 * publicity pertaining to distribution of the software without specific,
 * written prior permission.  The copyright holders make no representations
 * about the suitability of this software for any purpose.  It is provided "as
 * is" without express or implied warranty.
 *
 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
 * OF THIS SOFTWARE.
 */

#include <linux/export.h>
#include <linux/slab.h>
#include <linux/sort.h>

#include <drm/drm_atomic.h>
#include <drm/drm_blend.h>
#include <drm/drm_device.h>
#include <drm/drm_print.h>

#include "drm_crtc_internal.h"

/**
 * DOC: overview
 *
 * The basic plane composition model supported by standard plane properties only
 * has a source rectangle (in logical pixels within the &drm_framebuffer), with
 * sub-pixel accuracy, which is scaled up to a pixel-aligned destination
 * rectangle in the visible area of a &drm_crtc. The visible area of a CRTC is
 * defined by the horizontal and vertical visible pixels (stored in @hdisplay
 * and @vdisplay) of the requested mode (stored in &drm_crtc_state.mode). These
 * two rectangles are both stored in the &drm_plane_state.
 *
 * For the atomic ioctl the following standard (atomic) properties on the plane object
 * encode the basic plane composition model:
 *
 * SRC_X:
 * 	X coordinate offset for the source rectangle within the
 * 	&drm_framebuffer, in 16.16 fixed point. Must be positive.
 * SRC_Y:
 * 	Y coordinate offset for the source rectangle within the
 * 	&drm_framebuffer, in 16.16 fixed point. Must be positive.
 * SRC_W:
 * 	Width for the source rectangle within the &drm_framebuffer, in 16.16
 * 	fixed point. SRC_X plus SRC_W must be within the width of the source
 * 	framebuffer. Must be positive.
 * SRC_H:
 * 	Height for the source rectangle within the &drm_framebuffer, in 16.16
 * 	fixed point. SRC_Y plus SRC_H must be within the height of the source
 * 	framebuffer. Must be positive.
 * CRTC_X:
 * 	X coordinate offset for the destination rectangle. Can be negative.
 * CRTC_Y:
 * 	Y coordinate offset for the destination rectangle. Can be negative.
 * CRTC_W:
 * 	Width for the destination rectangle. CRTC_X plus CRTC_W can extend past
 * 	the currently visible horizontal area of the &drm_crtc.
 * CRTC_H:
 * 	Height for the destination rectangle. CRTC_Y plus CRTC_H can extend past
 * 	the currently visible vertical area of the &drm_crtc.
 * FB_ID:
 * 	Mode object ID of the &drm_framebuffer this plane should scan out.
 * CRTC_ID:
 * 	Mode object ID of the &drm_crtc this plane should be connected to.
 *
 * Note that the source rectangle must fully lie within the bounds of the
 * &drm_framebuffer. The destination rectangle can lie outside of the visible
 * area of the current mode of the CRTC. It must be apprpriately clipped by the
 * driver, which can be done by calling drm_plane_helper_check_update(). Drivers
 * are also allowed to round the subpixel sampling positions appropriately, but
 * only to the next full pixel. No pixel outside of the source rectangle may
 * ever be sampled, which is important when applying more sophisticated
 * filtering than just a bilinear one when scaling. The filtering mode when
 * scaling is unspecified.
 *
 * On top of this basic transformation additional properties can be exposed by
 * the driver:
 *
 * alpha:
 * 	Alpha is setup with drm_plane_create_alpha_property(). It controls the
 * 	plane-wide opacity, from transparent (0) to opaque (0xffff). It can be
 * 	combined with pixel alpha.
 *	The pixel values in the framebuffers are expected to not be
 *	pre-multiplied by the global alpha associated to the plane.
 *
 * rotation:
 *	Rotation is set up with drm_plane_create_rotation_property(). It adds a
 *	rotation and reflection step between the source and destination rectangles.
 *	Without this property the rectangle is only scaled, but not rotated or
 *	reflected.
 *
 *	Possbile values:
 *
 *	"rotate-<degrees>":
 *		Signals that a drm plane is rotated <degrees> degrees in counter
 *		clockwise direction.
 *
 *	"reflect-<axis>":
 *		Signals that the contents of a drm plane is reflected along the
 *		<axis> axis, in the same way as mirroring.
 *
 *	reflect-x::
 *
 *			|o |    | o|
 *			|  | -> |  |
 *			| v|    |v |
 *
 *	reflect-y::
 *
 *			|o |    | ^|
 *			|  | -> |  |
 *			| v|    |o |
 *
 * zpos:
 *	Z position is set up with drm_plane_create_zpos_immutable_property() and
 *	drm_plane_create_zpos_property(). It controls the visibility of overlapping
 *	planes. Without this property the primary plane is always below the cursor
 *	plane, and ordering between all other planes is undefined. The positive
 *	Z axis points towards the user, i.e. planes with lower Z position values
 *	are underneath planes with higher Z position values. Two planes with the
 *	same Z position value have undefined ordering. Note that the Z position
 *	value can also be immutable, to inform userspace about the hard-coded
 *	stacking of planes, see drm_plane_create_zpos_immutable_property(). If
 *	any plane has a zpos property (either mutable or immutable), then all
 *	planes shall have a zpos property.
 *
 * pixel blend mode:
 *	Pixel blend mode is set up with drm_plane_create_blend_mode_property().
 *	It adds a blend mode for alpha blending equation selection, describing
 *	how the pixels from the current plane are composited with the
 *	background.
 *
 *	 Three alpha blending equations are defined:
 *
 *	 "None":
 *		 Blend formula that ignores the pixel alpha::
 *
 *			 out.rgb = plane_alpha * fg.rgb +
 *				 (1 - plane_alpha) * bg.rgb
 *
 *	 "Pre-multiplied":
 *		 Blend formula that assumes the pixel color values
 *		 have been already pre-multiplied with the alpha
 *		 channel values::
 *
 *			 out.rgb = plane_alpha * fg.rgb +
 *				 (1 - (plane_alpha * fg.alpha)) * bg.rgb
 *
 *	 "Coverage":
 *		 Blend formula that assumes the pixel color values have not
 *		 been pre-multiplied and will do so when blending them to the
 *		 background color values::
 *
 *			 out.rgb = plane_alpha * fg.alpha * fg.rgb +
 *				 (1 - (plane_alpha * fg.alpha)) * bg.rgb
 *
 *	 Using the following symbols:
 *
 *	 "fg.rgb":
 *		 Each of the RGB component values from the plane's pixel
 *	 "fg.alpha":
 *		 Alpha component value from the plane's pixel. If the plane's
 *		 pixel format has no alpha component, then this is assumed to be
 *		 1.0. In these cases, this property has no effect, as all three
 *		 equations become equivalent.
 *	 "bg.rgb":
 *		 Each of the RGB component values from the background
 *	 "plane_alpha":
 *		 Plane alpha value set by the plane "alpha" property. If the
 *		 plane does not expose the "alpha" property, then this is
 *		 assumed to be 1.0
 *
 * Note that all the property extensions described here apply either to the
 * plane or the CRTC (e.g. for the background color, which currently is not
 * exposed and assumed to be black).
 *
 * SCALING_FILTER:
 *     Indicates scaling filter to be used for plane scaler
 *
 *     The value of this property can be one of the following:
 *
 *     Default:
 *             Driver's default scaling filter
 *     Nearest Neighbor:
 *             Nearest Neighbor scaling filter
 *
 * Drivers can set up this property for a plane by calling
 * drm_plane_create_scaling_filter_property
 */

/**
 * drm_plane_create_alpha_property - create a new alpha property
 * @plane: drm plane
 *
 * This function creates a generic, mutable, alpha property and enables support
 * for it in the DRM core. It is attached to @plane.
 *
 * The alpha property will be allowed to be within the bounds of 0
 * (transparent) to 0xffff (opaque).
 *
 * Returns:
 * 0 on success, negative error code on failure.
 */
int drm_plane_create_alpha_property(struct drm_plane *plane)
{
	struct drm_property *prop;

	prop = drm_property_create_range(plane->dev, 0, "alpha",
					 0, DRM_BLEND_ALPHA_OPAQUE);
	if (!prop)
		return -ENOMEM;

	drm_object_attach_property(&plane->base, prop, DRM_BLEND_ALPHA_OPAQUE);
	plane->alpha_property = prop;

	if (plane->state)
		plane->state->alpha = DRM_BLEND_ALPHA_OPAQUE;

	return 0;
}
EXPORT_SYMBOL(drm_plane_create_alpha_property);

/**
 * drm_plane_create_rotation_property - create a new rotation property
 * @plane: drm plane
 * @rotation: initial value of the rotation property
 * @supported_rotations: bitmask of supported rotations and reflections
 *
 * This creates a new property with the selected support for transformations.
 *
 * Since a rotation by 180° degress is the same as reflecting both along the x
 * and the y axis the rotation property is somewhat redundant. Drivers can use
 * drm_rotation_simplify() to normalize values of this property.
 *
 * The property exposed to userspace is a bitmask property (see
 * drm_property_create_bitmask()) called "rotation" and has the following
 * bitmask enumaration values:
 *
 * DRM_MODE_ROTATE_0:
 * 	"rotate-0"
 * DRM_MODE_ROTATE_90:
 * 	"rotate-90"
 * DRM_MODE_ROTATE_180:
 * 	"rotate-180"
 * DRM_MODE_ROTATE_270:
 * 	"rotate-270"
 * DRM_MODE_REFLECT_X:
 * 	"reflect-x"
 * DRM_MODE_REFLECT_Y:
 * 	"reflect-y"
 *
 * Rotation is the specified amount in degrees in counter clockwise direction,
 * the X and Y axis are within the source rectangle, i.e.  the X/Y axis before
 * rotation. After reflection, the rotation is applied to the image sampled from
 * the source rectangle, before scaling it to fit the destination rectangle.
 */
int drm_plane_create_rotation_property(struct drm_plane *plane,
				       unsigned int rotation,
				       unsigned int supported_rotations)
{
	static const struct drm_prop_enum_list props[] = {
		{ __builtin_ffs(DRM_MODE_ROTATE_0) - 1,   "rotate-0" },
		{ __builtin_ffs(DRM_MODE_ROTATE_90) - 1,  "rotate-90" },
		{ __builtin_ffs(DRM_MODE_ROTATE_180) - 1, "rotate-180" },
		{ __builtin_ffs(DRM_MODE_ROTATE_270) - 1, "rotate-270" },
		{ __builtin_ffs(DRM_MODE_REFLECT_X) - 1,  "reflect-x" },
		{ __builtin_ffs(DRM_MODE_REFLECT_Y) - 1,  "reflect-y" },
	};
	struct drm_property *prop;

	WARN_ON((supported_rotations & DRM_MODE_ROTATE_MASK) == 0);
	WARN_ON(!is_power_of_2(rotation & DRM_MODE_ROTATE_MASK));
	WARN_ON(rotation & ~supported_rotations);

	prop = drm_property_create_bitmask(plane->dev, 0, "rotation",
					   props, ARRAY_SIZE(props),
					   supported_rotations);
	if (!prop)
		return -ENOMEM;

	drm_object_attach_property(&plane->base, prop, rotation);

	if (plane->state)
		plane->state->rotation = rotation;

	plane->rotation_property = prop;

	return 0;
}
EXPORT_SYMBOL(drm_plane_create_rotation_property);

/**
 * drm_rotation_simplify() - Try to simplify the rotation
 * @rotation: Rotation to be simplified
 * @supported_rotations: Supported rotations
 *
 * Attempt to simplify the rotation to a form that is supported.
 * Eg. if the hardware supports everything except DRM_MODE_REFLECT_X
 * one could call this function like this:
 *
 * drm_rotation_simplify(rotation, DRM_MODE_ROTATE_0 |
 *                       DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_180 |
 *                       DRM_MODE_ROTATE_270 | DRM_MODE_REFLECT_Y);
 *
 * to eliminate the DRM_MODE_ROTATE_X flag. Depending on what kind of
 * transforms the hardware supports, this function may not
 * be able to produce a supported transform, so the caller should
 * check the result afterwards.
 */
unsigned int drm_rotation_simplify(unsigned int rotation,
				   unsigned int supported_rotations)
{
	if (rotation & ~supported_rotations) {
		rotation ^= DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y;
		rotation = (rotation & DRM_MODE_REFLECT_MASK) |
			    BIT((ffs(rotation & DRM_MODE_ROTATE_MASK) + 1)
			    % 4);
	}

	return rotation;
}
EXPORT_SYMBOL(drm_rotation_simplify);

/**
 * drm_plane_create_zpos_property - create mutable zpos property
 * @plane: drm plane
 * @zpos: initial value of zpos property
 * @min: minimal possible value of zpos property
 * @max: maximal possible value of zpos property
 *
 * This function initializes generic mutable zpos property and enables support
 * for it in drm core. Drivers can then attach this property to planes to enable
 * support for configurable planes arrangement during blending operation.
 * Drivers that attach a mutable zpos property to any plane should call the
 * drm_atomic_normalize_zpos() helper during their implementation of
 * &drm_mode_config_funcs.atomic_check(), which will update the normalized zpos
 * values and store them in &drm_plane_state.normalized_zpos. Usually min
 * should be set to 0 and max to maximal number of planes for given crtc - 1.
 *
 * If zpos of some planes cannot be changed (like fixed background or
 * cursor/topmost planes), drivers shall adjust the min/max values and assign
 * those planes immutable zpos properties with lower or higher values (for more
 * information, see drm_plane_create_zpos_immutable_property() function). In such
 * case drivers shall also assign proper initial zpos values for all planes in
 * its plane_reset() callback, so the planes will be always sorted properly.
 *
 * See also drm_atomic_normalize_zpos().
 *
 * The property exposed to userspace is called "zpos".
 *
 * Returns:
 * Zero on success, negative errno on failure.
 */
int drm_plane_create_zpos_property(struct drm_plane *plane,
				   unsigned int zpos,
				   unsigned int min, unsigned int max)
{
	struct drm_property *prop;

	prop = drm_property_create_range(plane->dev, 0, "zpos", min, max);
	if (!prop)
		return -ENOMEM;

	drm_object_attach_property(&plane->base, prop, zpos);

	plane->zpos_property = prop;

	if (plane->state) {
		plane->state->zpos = zpos;
		plane->state->normalized_zpos = zpos;
	}

	return 0;
}
EXPORT_SYMBOL(drm_plane_create_zpos_property);

/**
 * drm_plane_create_zpos_immutable_property - create immuttable zpos property
 * @plane: drm plane
 * @zpos: value of zpos property
 *
 * This function initializes generic immutable zpos property and enables
 * support for it in drm core. Using this property driver lets userspace
 * to get the arrangement of the planes for blending operation and notifies
 * it that the hardware (or driver) doesn't support changing of the planes'
 * order. For mutable zpos see drm_plane_create_zpos_property().
 *
 * The property exposed to userspace is called "zpos".
 *
 * Returns:
 * Zero on success, negative errno on failure.
 */
int drm_plane_create_zpos_immutable_property(struct drm_plane *plane,
					     unsigned int zpos)
{
	struct drm_property *prop;

	prop = drm_property_create_range(plane->dev, DRM_MODE_PROP_IMMUTABLE,
					 "zpos", zpos, zpos);
	if (!prop)
		return -ENOMEM;

	drm_object_attach_property(&plane->base, prop, zpos);

	plane->zpos_property = prop;

	if (plane->state) {
		plane->state->zpos = zpos;
		plane->state->normalized_zpos = zpos;
	}

	return 0;
}
EXPORT_SYMBOL(drm_plane_create_zpos_immutable_property);

static int drm_atomic_state_zpos_cmp(const void *a, const void *b)
{
	const struct drm_plane_state *sa = *(struct drm_plane_state **)a;
	const struct drm_plane_state *sb = *(struct drm_plane_state **)b;

	if (sa->zpos != sb->zpos)
		return sa->zpos - sb->zpos;
	else
		return sa->plane->base.id - sb->plane->base.id;
}

static int drm_atomic_helper_crtc_normalize_zpos(struct drm_crtc *crtc,
					  struct drm_crtc_state *crtc_state)
{
	struct drm_atomic_state *state = crtc_state->state;
	struct drm_device *dev = crtc->dev;
	int total_planes = dev->mode_config.num_total_plane;
	struct drm_plane_state **states;
	struct drm_plane *plane;
	int i, n = 0;
	int ret = 0;

	DRM_DEBUG_ATOMIC("[CRTC:%d:%s] calculating normalized zpos values\n",
			 crtc->base.id, crtc->name);

	states = kmalloc_array(total_planes, sizeof(*states), GFP_KERNEL);
	if (!states)
		return -ENOMEM;

	/*
	 * Normalization process might create new states for planes which
	 * normalized_zpos has to be recalculated.
	 */
	drm_for_each_plane_mask(plane, dev, crtc_state->plane_mask) {
		struct drm_plane_state *plane_state =
			drm_atomic_get_plane_state(state, plane);
		if (IS_ERR(plane_state)) {
			ret = PTR_ERR(plane_state);
			goto done;
		}
		states[n++] = plane_state;
		DRM_DEBUG_ATOMIC("[PLANE:%d:%s] processing zpos value %d\n",
				 plane->base.id, plane->name,
				 plane_state->zpos);
	}

	sort(states, n, sizeof(*states), drm_atomic_state_zpos_cmp, NULL);

	for (i = 0; i < n; i++) {
		plane = states[i]->plane;

		states[i]->normalized_zpos = i;
		DRM_DEBUG_ATOMIC("[PLANE:%d:%s] normalized zpos value %d\n",
				 plane->base.id, plane->name, i);
	}
	crtc_state->zpos_changed = true;

done:
	kfree(states);
	return ret;
}

/**
 * drm_atomic_normalize_zpos - calculate normalized zpos values for all crtcs
 * @dev: DRM device
 * @state: atomic state of DRM device
 *
 * This function calculates normalized zpos value for all modified planes in
 * the provided atomic state of DRM device.
 *
 * For every CRTC this function checks new states of all planes assigned to
 * it and calculates normalized zpos value for these planes. Planes are compared
 * first by their zpos values, then by plane id (if zpos is equal). The plane
 * with lowest zpos value is at the bottom. The &drm_plane_state.normalized_zpos
 * is then filled with unique values from 0 to number of active planes in crtc
 * minus one.
 *
 * RETURNS
 * Zero for success or -errno
 */
int drm_atomic_normalize_zpos(struct drm_device *dev,
			      struct drm_atomic_state *state)
{
	struct drm_crtc *crtc;
	struct drm_crtc_state *old_crtc_state, *new_crtc_state;
	struct drm_plane *plane;
	struct drm_plane_state *old_plane_state, *new_plane_state;
	int i, ret = 0;

	for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
		crtc = new_plane_state->crtc;
		if (!crtc)
			continue;
		if (old_plane_state->zpos != new_plane_state->zpos) {
			new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
			new_crtc_state->zpos_changed = true;
		}
	}

	for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
		if (old_crtc_state->plane_mask != new_crtc_state->plane_mask ||
		    new_crtc_state->zpos_changed) {
			ret = drm_atomic_helper_crtc_normalize_zpos(crtc,
								    new_crtc_state);
			if (ret)
				return ret;
		}
	}
	return 0;
}
EXPORT_SYMBOL(drm_atomic_normalize_zpos);

/**
 * drm_plane_create_blend_mode_property - create a new blend mode property
 * @plane: drm plane
 * @supported_modes: bitmask of supported modes, must include
 *		     BIT(DRM_MODE_BLEND_PREMULTI). Current DRM assumption is
 *		     that alpha is premultiplied, and old userspace can break if
 *		     the property defaults to anything else.
 *
 * This creates a new property describing the blend mode.
 *
 * The property exposed to userspace is an enumeration property (see
 * drm_property_create_enum()) called "pixel blend mode" and has the
 * following enumeration values:
 *
 * "None":
 *	Blend formula that ignores the pixel alpha.
 *
 * "Pre-multiplied":
 *	Blend formula that assumes the pixel color values have been already
 *	pre-multiplied with the alpha channel values.
 *
 * "Coverage":
 *	Blend formula that assumes the pixel color values have not been
 *	pre-multiplied and will do so when blending them to the background color
 *	values.
 *
 * RETURNS:
 * Zero for success or -errno
 */
int drm_plane_create_blend_mode_property(struct drm_plane *plane,
					 unsigned int supported_modes)
{
	struct drm_device *dev = plane->dev;
	struct drm_property *prop;
	static const struct drm_prop_enum_list props[] = {
		{ DRM_MODE_BLEND_PIXEL_NONE, "None" },
		{ DRM_MODE_BLEND_PREMULTI, "Pre-multiplied" },
		{ DRM_MODE_BLEND_COVERAGE, "Coverage" },
	};
	unsigned int valid_mode_mask = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
				       BIT(DRM_MODE_BLEND_PREMULTI)   |
				       BIT(DRM_MODE_BLEND_COVERAGE);
	int i;

	if (WARN_ON((supported_modes & ~valid_mode_mask) ||
		    ((supported_modes & BIT(DRM_MODE_BLEND_PREMULTI)) == 0)))
		return -EINVAL;

	prop = drm_property_create(dev, DRM_MODE_PROP_ENUM,
				   "pixel blend mode",
				   hweight32(supported_modes));
	if (!prop)
		return -ENOMEM;

	for (i = 0; i < ARRAY_SIZE(props); i++) {
		int ret;

		if (!(BIT(props[i].type) & supported_modes))
			continue;

		ret = drm_property_add_enum(prop, props[i].type,
					    props[i].name);

		if (ret) {
			drm_property_destroy(dev, prop);

			return ret;
		}
	}

	drm_object_attach_property(&plane->base, prop, DRM_MODE_BLEND_PREMULTI);
	plane->blend_mode_property = prop;

	return 0;
}
EXPORT_SYMBOL(drm_plane_create_blend_mode_property);
