vmwgfx: Add page flip support
Signed-off-by: Jakob Bornecrantz <jakob@vmware.com> Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
bd49ae46f8
commit
b5ec427e8d
|
@ -1681,6 +1681,70 @@ int vmw_du_update_layout(struct vmw_private *dev_priv, unsigned num,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int vmw_du_page_flip(struct drm_crtc *crtc,
|
||||
struct drm_framebuffer *fb,
|
||||
struct drm_pending_vblank_event *event)
|
||||
{
|
||||
struct vmw_private *dev_priv = vmw_priv(crtc->dev);
|
||||
struct drm_framebuffer *old_fb = crtc->fb;
|
||||
struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(fb);
|
||||
struct drm_file *file_priv = event->base.file_priv;
|
||||
struct vmw_fence_obj *fence = NULL;
|
||||
struct drm_clip_rect clips;
|
||||
int ret;
|
||||
|
||||
/* require ScreenObject support for page flipping */
|
||||
if (!dev_priv->sou_priv)
|
||||
return -ENOSYS;
|
||||
|
||||
if (!vmw_kms_screen_object_flippable(dev_priv, crtc))
|
||||
return -EINVAL;
|
||||
|
||||
crtc->fb = fb;
|
||||
|
||||
/* do a full screen dirty update */
|
||||
clips.x1 = clips.y1 = 0;
|
||||
clips.x2 = fb->width;
|
||||
clips.y2 = fb->height;
|
||||
|
||||
if (vfb->dmabuf)
|
||||
ret = do_dmabuf_dirty_sou(file_priv, dev_priv, vfb,
|
||||
0, 0, &clips, 1, 1, &fence);
|
||||
else
|
||||
ret = do_surface_dirty_sou(dev_priv, file_priv, vfb,
|
||||
0, 0, &clips, 1, 1, &fence);
|
||||
|
||||
|
||||
if (ret != 0)
|
||||
goto out_no_fence;
|
||||
if (!fence) {
|
||||
ret = -EINVAL;
|
||||
goto out_no_fence;
|
||||
}
|
||||
|
||||
ret = vmw_event_fence_action_queue(file_priv, fence,
|
||||
&event->base,
|
||||
&event->event.tv_sec,
|
||||
&event->event.tv_usec,
|
||||
true);
|
||||
|
||||
/*
|
||||
* No need to hold on to this now. The only cleanup
|
||||
* we need to do if we fail is unref the fence.
|
||||
*/
|
||||
vmw_fence_obj_unreference(&fence);
|
||||
|
||||
if (vmw_crtc_to_du(crtc)->is_implicit)
|
||||
vmw_kms_screen_object_update_implicit_fb(dev_priv, crtc);
|
||||
|
||||
return ret;
|
||||
|
||||
out_no_fence:
|
||||
crtc->fb = old_fb;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void vmw_du_crtc_save(struct drm_crtc *crtc)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -121,6 +121,9 @@ struct vmw_display_unit {
|
|||
* Shared display unit functions - vmwgfx_kms.c
|
||||
*/
|
||||
void vmw_display_unit_cleanup(struct vmw_display_unit *du);
|
||||
int vmw_du_page_flip(struct drm_crtc *crtc,
|
||||
struct drm_framebuffer *fb,
|
||||
struct drm_pending_vblank_event *event);
|
||||
void vmw_du_crtc_save(struct drm_crtc *crtc);
|
||||
void vmw_du_crtc_restore(struct drm_crtc *crtc);
|
||||
void vmw_du_crtc_gamma_set(struct drm_crtc *crtc,
|
||||
|
@ -154,5 +157,10 @@ int vmw_kms_init_screen_object_display(struct vmw_private *dev_priv);
|
|||
int vmw_kms_close_screen_object_display(struct vmw_private *dev_priv);
|
||||
int vmw_kms_sou_update_layout(struct vmw_private *dev_priv, unsigned num,
|
||||
struct drm_vmw_rect *rects);
|
||||
bool vmw_kms_screen_object_flippable(struct vmw_private *dev_priv,
|
||||
struct drm_crtc *crtc);
|
||||
void vmw_kms_screen_object_update_implicit_fb(struct vmw_private *dev_priv,
|
||||
struct drm_crtc *crtc);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -394,6 +394,7 @@ static struct drm_crtc_funcs vmw_screen_object_crtc_funcs = {
|
|||
.gamma_set = vmw_du_crtc_gamma_set,
|
||||
.destroy = vmw_sou_crtc_destroy,
|
||||
.set_config = vmw_sou_crtc_set_config,
|
||||
.page_flip = vmw_du_page_flip,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -535,3 +536,36 @@ int vmw_kms_close_screen_object_display(struct vmw_private *dev_priv)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if this unit can be page flipped.
|
||||
* Must be called with the mode_config mutex held.
|
||||
*/
|
||||
bool vmw_kms_screen_object_flippable(struct vmw_private *dev_priv,
|
||||
struct drm_crtc *crtc)
|
||||
{
|
||||
struct vmw_screen_object_unit *sou = vmw_crtc_to_sou(crtc);
|
||||
|
||||
if (!sou->base.is_implicit)
|
||||
return true;
|
||||
|
||||
if (dev_priv->sou_priv->num_implicit != 1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the implicit fb to the current fb of this crtc.
|
||||
* Must be called with the mode_config mutex held.
|
||||
*/
|
||||
void vmw_kms_screen_object_update_implicit_fb(struct vmw_private *dev_priv,
|
||||
struct drm_crtc *crtc)
|
||||
{
|
||||
struct vmw_screen_object_unit *sou = vmw_crtc_to_sou(crtc);
|
||||
|
||||
BUG_ON(!sou->base.is_implicit);
|
||||
|
||||
dev_priv->sou_priv->implicit_fb =
|
||||
vmw_framebuffer_to_vfb(sou->base.crtc.fb);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue