drm/qxl: simple crtc page flipping emulated using buffer copy
Signed-off-by: Andreas Pokorny <andreas.pokorny@canonical.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
Родитель
6ba59f3b5c
Коммит
058e9f5c82
|
@ -187,6 +187,54 @@ static void qxl_crtc_destroy(struct drm_crtc *crtc)
|
|||
kfree(qxl_crtc);
|
||||
}
|
||||
|
||||
static int qxl_crtc_page_flip(struct drm_crtc *crtc,
|
||||
struct drm_framebuffer *fb,
|
||||
struct drm_pending_vblank_event *event,
|
||||
uint32_t page_flip_flags)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct qxl_device *qdev = dev->dev_private;
|
||||
struct qxl_crtc *qcrtc = to_qxl_crtc(crtc);
|
||||
struct qxl_framebuffer *qfb_src = to_qxl_framebuffer(fb);
|
||||
struct qxl_framebuffer *qfb_old = to_qxl_framebuffer(crtc->primary->fb);
|
||||
struct qxl_bo *bo_old = gem_to_qxl_bo(qfb_old->obj);
|
||||
struct qxl_bo *bo = gem_to_qxl_bo(qfb_src->obj);
|
||||
unsigned long flags;
|
||||
struct drm_clip_rect norect = {
|
||||
.x1 = 0,
|
||||
.y1 = 0,
|
||||
.x2 = fb->width,
|
||||
.y2 = fb->height
|
||||
};
|
||||
int inc = 1;
|
||||
int one_clip_rect = 1;
|
||||
int ret = 0;
|
||||
|
||||
crtc->primary->fb = fb;
|
||||
bo_old->is_primary = false;
|
||||
bo->is_primary = true;
|
||||
|
||||
ret = qxl_bo_reserve(bo, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
qxl_draw_dirty_fb(qdev, qfb_src, bo, 0, 0,
|
||||
&norect, one_clip_rect, inc);
|
||||
|
||||
drm_vblank_get(dev, qcrtc->index);
|
||||
|
||||
if (event) {
|
||||
spin_lock_irqsave(&dev->event_lock, flags);
|
||||
drm_send_vblank_event(dev, qcrtc->index, event);
|
||||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||
}
|
||||
drm_vblank_put(dev, qcrtc->index);
|
||||
|
||||
qxl_bo_unreserve(bo);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
qxl_hide_cursor(struct qxl_device *qdev)
|
||||
{
|
||||
|
@ -374,6 +422,7 @@ static const struct drm_crtc_funcs qxl_crtc_funcs = {
|
|||
.cursor_move = qxl_crtc_cursor_move,
|
||||
.set_config = drm_crtc_helper_set_config,
|
||||
.destroy = qxl_crtc_destroy,
|
||||
.page_flip = qxl_crtc_page_flip,
|
||||
};
|
||||
|
||||
static void qxl_user_framebuffer_destroy(struct drm_framebuffer *fb)
|
||||
|
|
|
@ -84,6 +84,7 @@ static const struct file_operations qxl_fops = {
|
|||
.release = drm_release,
|
||||
.unlocked_ioctl = drm_ioctl,
|
||||
.poll = drm_poll,
|
||||
.read = drm_read,
|
||||
.mmap = qxl_mmap,
|
||||
};
|
||||
|
||||
|
@ -195,6 +196,20 @@ static int qxl_pm_restore(struct device *dev)
|
|||
return qxl_drm_resume(drm_dev, false);
|
||||
}
|
||||
|
||||
static u32 qxl_noop_get_vblank_counter(struct drm_device *dev, int crtc)
|
||||
{
|
||||
return dev->vblank[crtc].count.counter;
|
||||
}
|
||||
|
||||
static int qxl_noop_enable_vblank(struct drm_device *dev, int crtc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void qxl_noop_disable_vblank(struct drm_device *dev, int crtc)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops qxl_pm_ops = {
|
||||
.suspend = qxl_pm_suspend,
|
||||
.resume = qxl_pm_resume,
|
||||
|
@ -216,6 +231,9 @@ static struct drm_driver qxl_driver = {
|
|||
DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
|
||||
.load = qxl_driver_load,
|
||||
.unload = qxl_driver_unload,
|
||||
.get_vblank_counter = qxl_noop_get_vblank_counter,
|
||||
.enable_vblank = qxl_noop_enable_vblank,
|
||||
.disable_vblank = qxl_noop_disable_vblank,
|
||||
|
||||
.dumb_create = qxl_mode_dumb_create,
|
||||
.dumb_map_offset = qxl_mode_dumb_mmap,
|
||||
|
|
|
@ -298,6 +298,9 @@ int qxl_driver_unload(struct drm_device *dev)
|
|||
|
||||
if (qdev == NULL)
|
||||
return 0;
|
||||
|
||||
drm_vblank_cleanup(dev);
|
||||
|
||||
qxl_modeset_fini(qdev);
|
||||
qxl_device_fini(qdev);
|
||||
|
||||
|
@ -325,15 +328,20 @@ int qxl_driver_load(struct drm_device *dev, unsigned long flags)
|
|||
if (r)
|
||||
goto out;
|
||||
|
||||
r = drm_vblank_init(dev, 1);
|
||||
if (r)
|
||||
goto unload;
|
||||
|
||||
r = qxl_modeset_init(qdev);
|
||||
if (r) {
|
||||
qxl_driver_unload(dev);
|
||||
goto out;
|
||||
}
|
||||
if (r)
|
||||
goto unload;
|
||||
|
||||
drm_kms_helper_poll_init(qdev->ddev);
|
||||
|
||||
return 0;
|
||||
unload:
|
||||
qxl_driver_unload(dev);
|
||||
|
||||
out:
|
||||
kfree(qdev);
|
||||
return r;
|
||||
|
|
Загрузка…
Ссылка в новой задаче