Skip to content

Commit

Permalink
vmwgfx: Add page flip support
Browse files Browse the repository at this point in the history
Signed-off-by: Jakob Bornecrantz <jakob@vmware.com>
Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
  • Loading branch information
Jakob Bornecrantz authored and Dave Airlie committed Feb 13, 2012
1 parent bd49ae4 commit b5ec427
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 0 deletions.
64 changes: 64 additions & 0 deletions drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
}
Expand Down
8 changes: 8 additions & 0 deletions drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
34 changes: 34 additions & 0 deletions drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};

/*
Expand Down Expand Up @@ -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);
}

0 comments on commit b5ec427

Please sign in to comment.