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: Javier Martinez Canillas <javierm@redhat.com> Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de> Signed-off-by: Noralf Trønnes <noralf@tronnes.org> Link: https://patchwork.freedesktop.org/patch/msgid/20221122-gud-shadow-plane-v2-3-435037990a83@tronnes.org
This commit is contained in:
parent
f531d19882
commit
754a6ca85c
@ -333,15 +333,49 @@ void gud_clear_damage(struct gud_device *gdrm)
|
||||
gdrm->damage.y2 = 0;
|
||||
}
|
||||
|
||||
static void gud_flush_damage(struct gud_device *gdrm, struct drm_framebuffer *fb,
|
||||
struct drm_rect *damage)
|
||||
{
|
||||
const struct drm_format_info *format;
|
||||
unsigned int i, lines;
|
||||
size_t pitch;
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
rect.y1 += i * lines;
|
||||
rect.y2 = min_t(u32, rect.y1 + lines, damage->y2);
|
||||
|
||||
ret = gud_flush_rect(gdrm, fb, format, &rect);
|
||||
if (ret) {
|
||||
if (ret != -ENODEV && ret != -ECONNRESET &&
|
||||
ret != -ESHUTDOWN && ret != -EPROTO)
|
||||
dev_err_ratelimited(fb->dev->dev,
|
||||
"Failed to flush framebuffer: error=%d\n", ret);
|
||||
gdrm->prev_flush_failed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gud_flush_work(struct work_struct *work)
|
||||
{
|
||||
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;
|
||||
int idx;
|
||||
|
||||
if (!drm_dev_enter(&gdrm->drm, &idx))
|
||||
return;
|
||||
@ -356,35 +390,7 @@ void gud_flush_work(struct work_struct *work)
|
||||
if (!fb)
|
||||
goto out;
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
rect.y1 += i * lines;
|
||||
rect.y2 = min_t(u32, rect.y1 + lines, damage.y2);
|
||||
|
||||
ret = gud_flush_rect(gdrm, fb, format, &rect);
|
||||
if (ret) {
|
||||
if (ret != -ENODEV && ret != -ECONNRESET &&
|
||||
ret != -ESHUTDOWN && ret != -EPROTO)
|
||||
dev_err_ratelimited(fb->dev->dev,
|
||||
"Failed to flush framebuffer: error=%d\n", ret);
|
||||
gdrm->prev_flush_failed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
gdrm->prev_flush_failed = false;
|
||||
}
|
||||
gud_flush_damage(gdrm, fb, &damage);
|
||||
|
||||
drm_framebuffer_put(fb);
|
||||
out:
|
||||
|
Loading…
x
Reference in New Issue
Block a user