linux/drivers/gpu/drm/vkms/vkms_composer.c

// SPDX-License-Identifier: GPL-2.0+

#include <linux/crc32.h>

#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_blend.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_fixed.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_vblank.h>
#include <linux/minmax.h>

#include "vkms_drv.h"

static u16 pre_mul_blend_channel(u16 src, u16 dst, u16 alpha)
{}

/**
 * pre_mul_alpha_blend - alpha blending equation
 * @frame_info: Source framebuffer's metadata
 * @stage_buffer: The line with the pixels from src_plane
 * @output_buffer: A line buffer that receives all the blends output
 *
 * Using the information from the `frame_info`, this blends only the
 * necessary pixels from the `stage_buffer` to the `output_buffer`
 * using premultiplied blend formula.
 *
 * The current DRM assumption is that pixel color values have been already
 * pre-multiplied with the alpha channel values. See more
 * drm_plane_create_blend_mode_property(). Also, this formula assumes a
 * completely opaque background.
 */
static void pre_mul_alpha_blend(struct vkms_frame_info *frame_info,
				struct line_buffer *stage_buffer,
				struct line_buffer *output_buffer)
{}

static int get_y_pos(struct vkms_frame_info *frame_info, int y)
{}

static bool check_limit(struct vkms_frame_info *frame_info, int pos)
{}

static void fill_background(const struct pixel_argb_u16 *background_color,
			    struct line_buffer *output_buffer)
{}

// lerp(a, b, t) = a + (b - a) * t
static u16 lerp_u16(u16 a, u16 b, s64 t)
{}

static s64 get_lut_index(const struct vkms_color_lut *lut, u16 channel_value)
{}

/*
 * This enum is related to the positions of the variables inside
 * `struct drm_color_lut`, so the order of both needs to be the same.
 */
enum lut_channel {};

static u16 apply_lut_to_channel_value(const struct vkms_color_lut *lut, u16 channel_value,
				      enum lut_channel channel)
{}

static void apply_lut(const struct vkms_crtc_state *crtc_state, struct line_buffer *output_buffer)
{}

/**
 * blend - blend the pixels from all planes and compute crc
 * @wb: The writeback frame buffer metadata
 * @crtc_state: The crtc state
 * @crc32: The crc output of the final frame
 * @output_buffer: A buffer of a row that will receive the result of the blend(s)
 * @stage_buffer: The line with the pixels from plane being blend to the output
 * @row_size: The size, in bytes, of a single row
 *
 * This function blends the pixels (Using the `pre_mul_alpha_blend`)
 * from all planes, calculates the crc32 of the output from the former step,
 * and, if necessary, convert and store the output to the writeback buffer.
 */
static void blend(struct vkms_writeback_job *wb,
		  struct vkms_crtc_state *crtc_state,
		  u32 *crc32, struct line_buffer *stage_buffer,
		  struct line_buffer *output_buffer, size_t row_size)
{}

static int check_format_funcs(struct vkms_crtc_state *crtc_state,
			      struct vkms_writeback_job *active_wb)
{}

static int check_iosys_map(struct vkms_crtc_state *crtc_state)
{}

static int compose_active_planes(struct vkms_writeback_job *active_wb,
				 struct vkms_crtc_state *crtc_state,
				 u32 *crc32)
{}

/**
 * vkms_composer_worker - ordered work_struct to compute CRC
 *
 * @work: work_struct
 *
 * Work handler for composing and computing CRCs. work_struct scheduled in
 * an ordered workqueue that's periodically scheduled to run by
 * vkms_vblank_simulate() and flushed at vkms_atomic_commit_tail().
 */
void vkms_composer_worker(struct work_struct *work)
{}

static const char * const pipe_crc_sources[] =;

const char *const *vkms_get_crc_sources(struct drm_crtc *crtc,
					size_t *count)
{}

static int vkms_crc_parse_source(const char *src_name, bool *enabled)
{}

int vkms_verify_crc_source(struct drm_crtc *crtc, const char *src_name,
			   size_t *values_cnt)
{}

void vkms_set_composer(struct vkms_output *out, bool enabled)
{}

int vkms_set_crc_source(struct drm_crtc *crtc, const char *src_name)
{}