Commit 754a6ca8 authored by Noralf Trønnes's avatar Noralf Trønnes
Browse files

drm/gud: Split up gud_flush_work()



In preparation for inlining synchronous flushing split out the part of
gud_flush_work() that can be shared by the sync and async code paths.

Reviewed-by: default avatarJavier Martinez Canillas <javierm@redhat.com>
Reviewed-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: default avatarNoralf Trønnes <noralf@tronnes.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20221122-gud-shadow-plane-v2-3-435037990a83@tronnes.org
parent f531d198
Loading
Loading
Loading
Loading
+31 −25
Original line number Diff line number Diff line
@@ -333,45 +333,30 @@ void gud_clear_damage(struct gud_device *gdrm)
	gdrm->damage.y2 = 0;
}

void gud_flush_work(struct work_struct *work)
static void gud_flush_damage(struct gud_device *gdrm, struct drm_framebuffer *fb,
			     struct drm_rect *damage)
{
	struct gud_device *gdrm = container_of(work, struct gud_device, work);
	const struct drm_format_info *format;
	struct drm_framebuffer *fb;
	struct drm_rect damage;
	unsigned int i, lines;
	int idx, ret = 0;
	size_t pitch;

	if (!drm_dev_enter(&gdrm->drm, &idx))
		return;

	mutex_lock(&gdrm->damage_lock);
	fb = gdrm->fb;
	gdrm->fb = NULL;
	damage = gdrm->damage;
	gud_clear_damage(gdrm);
	mutex_unlock(&gdrm->damage_lock);

	if (!fb)
		goto out;
	int ret;

	format = fb->format;
	if (format->format == DRM_FORMAT_XRGB8888 && gdrm->xrgb8888_emulation_format)
		format = gdrm->xrgb8888_emulation_format;

	/* Split update if it's too big */
	pitch = drm_format_info_min_pitch(format, 0, drm_rect_width(&damage));
	lines = drm_rect_height(&damage);
	pitch = drm_format_info_min_pitch(format, 0, drm_rect_width(damage));
	lines = drm_rect_height(damage);

	if (gdrm->bulk_len < lines * pitch)
		lines = gdrm->bulk_len / pitch;

	for (i = 0; i < DIV_ROUND_UP(drm_rect_height(&damage), lines); i++) {
		struct drm_rect rect = damage;
	for (i = 0; i < DIV_ROUND_UP(drm_rect_height(damage), lines); i++) {
		struct drm_rect rect = *damage;

		rect.y1 += i * lines;
		rect.y2 = min_t(u32, rect.y1 + lines, damage.y2);
		rect.y2 = min_t(u32, rect.y1 + lines, damage->y2);

		ret = gud_flush_rect(gdrm, fb, format, &rect);
		if (ret) {
@@ -382,9 +367,30 @@ void gud_flush_work(struct work_struct *work)
			gdrm->prev_flush_failed = true;
			break;
		}

		gdrm->prev_flush_failed = false;
	}
}

void gud_flush_work(struct work_struct *work)
{
	struct gud_device *gdrm = container_of(work, struct gud_device, work);
	struct drm_framebuffer *fb;
	struct drm_rect damage;
	int idx;

	if (!drm_dev_enter(&gdrm->drm, &idx))
		return;

	mutex_lock(&gdrm->damage_lock);
	fb = gdrm->fb;
	gdrm->fb = NULL;
	damage = gdrm->damage;
	gud_clear_damage(gdrm);
	mutex_unlock(&gdrm->damage_lock);

	if (!fb)
		goto out;

	gud_flush_damage(gdrm, fb, &damage);

	drm_framebuffer_put(fb);
out: