Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b5ec427e authored by Jakob Bornecrantz's avatar Jakob Bornecrantz Committed by Dave Airlie
Browse files

vmwgfx: Add page flip support

parent bd49ae46
Loading
Loading
Loading
Loading
+64 −0
Original line number Diff line number Diff line
@@ -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)
{
}
+8 −0
Original line number Diff line number Diff line
@@ -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
+34 −0
Original line number Diff line number Diff line
@@ -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);
}