From: Thomas Hellstrom Date: Fri, 12 Feb 2016 07:32:08 +0000 (+0100) Subject: drm/vmwgfx: Fix screen object page flips for large framebuffers X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=897b818077f3c11eda82ead57fd173c7f12f9796;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git drm/vmwgfx: Fix screen object page flips for large framebuffers For page flips the framebuffer may be much larger than the crtc scanout area and may be attached to multiple crtcs. When flipping a crtc, make sure we dirty only that crtc's area of the framebuffer. Signed-off-by: Thomas Hellstrom Reviewed-by: Sinclair Yeh --- diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index b221a8c40282..29bec974464c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -663,9 +663,8 @@ static int vmw_framebuffer_dmabuf_dirty(struct drm_framebuffer *framebuffer, break; case vmw_du_screen_object: ret = vmw_kms_sou_do_dmabuf_dirty(dev_priv, &vfbd->base, - clips, num_clips, increment, - true, - NULL); + clips, NULL, num_clips, + increment, true, NULL); break; case vmw_du_legacy: ret = vmw_kms_ldu_do_dmabuf_dirty(dev_priv, &vfbd->base, 0, 0, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h index edd81503516d..d41928c12a42 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h @@ -287,6 +287,7 @@ int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv, int vmw_kms_sou_do_dmabuf_dirty(struct vmw_private *dev_priv, struct vmw_framebuffer *framebuffer, struct drm_clip_rect *clips, + struct drm_vmw_rect *vclips, unsigned num_clips, int increment, bool interruptible, struct vmw_fence_obj **out_fence); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index cbc1fbaa3d8e..c0de3b8d4e5d 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c @@ -470,7 +470,7 @@ static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *old_fb = crtc->primary->fb; struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(fb); struct vmw_fence_obj *fence = NULL; - struct drm_clip_rect clips; + struct drm_vmw_rect vclips; int ret; /* require ScreenObject support for page flipping */ @@ -483,17 +483,18 @@ static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc, crtc->primary->fb = fb; /* do a full screen dirty update */ - clips.x1 = clips.y1 = 0; - clips.x2 = fb->width; - clips.y2 = fb->height; + vclips.x = crtc->x; + vclips.y = crtc->y; + vclips.w = crtc->mode.hdisplay; + vclips.h = crtc->mode.vdisplay; if (vfb->dmabuf) ret = vmw_kms_sou_do_dmabuf_dirty(dev_priv, vfb, - &clips, 1, 1, + NULL, &vclips, 1, 1, true, &fence); else ret = vmw_kms_sou_do_surface_dirty(dev_priv, vfb, - &clips, NULL, NULL, + NULL, &vclips, NULL, 0, 0, 1, 1, &fence); @@ -919,6 +920,8 @@ static void vmw_sou_dmabuf_clip(struct vmw_kms_dirty *dirty) * @dev_priv: Pointer to the device private structure. * @framebuffer: Pointer to the dma-buffer backed framebuffer. * @clips: Array of clip rects. + * @vclips: Alternate array of clip rects. Either @clips or @vclips must + * be NULL. * @num_clips: Number of clip rects in @clips. * @increment: Increment to use when looping over @clips. * @interruptible: Whether to perform waits interruptible if possible. @@ -932,6 +935,7 @@ static void vmw_sou_dmabuf_clip(struct vmw_kms_dirty *dirty) int vmw_kms_sou_do_dmabuf_dirty(struct vmw_private *dev_priv, struct vmw_framebuffer *framebuffer, struct drm_clip_rect *clips, + struct drm_vmw_rect *vclips, unsigned num_clips, int increment, bool interruptible, struct vmw_fence_obj **out_fence) @@ -955,7 +959,7 @@ int vmw_kms_sou_do_dmabuf_dirty(struct vmw_private *dev_priv, dirty.clip = vmw_sou_dmabuf_clip; dirty.fifo_reserve_size = sizeof(struct vmw_kms_sou_dmabuf_blit) * num_clips; - ret = vmw_kms_helper_dirty(dev_priv, framebuffer, clips, NULL, + ret = vmw_kms_helper_dirty(dev_priv, framebuffer, clips, vclips, 0, 0, num_clips, increment, &dirty); vmw_kms_helper_buffer_finish(dev_priv, NULL, buf, out_fence, NULL);