summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorAlon Levy <alevy@redhat.com>2012-10-24 13:17:17 +0200
committerAlon Levy <alevy@redhat.com>2012-10-24 13:17:17 +0200
commit25780ae6898a7846b95522698330bda18d6109bc (patch)
tree7523c9d50ac4d0cdc62e0dec0f506edb81d97512 /drivers/gpu
parentfa68ed7a501dbf6ea6e3ef433793355edffb3536 (diff)
qxl: store surfaces (not updated yet) and don't issue wrong sized update_areaHEADdummy
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/qxl/qxl_cmd.c10
-rw-r--r--drivers/gpu/drm/qxl/qxl_drv.h20
2 files changed, 30 insertions, 0 deletions
diff --git a/drivers/gpu/drm/qxl/qxl_cmd.c b/drivers/gpu/drm/qxl/qxl_cmd.c
index b3b18b89985..71fe77fa86e 100644
--- a/drivers/gpu/drm/qxl/qxl_cmd.c
+++ b/drivers/gpu/drm/qxl/qxl_cmd.c
@@ -242,6 +242,16 @@ done:
void qxl_io_update_area(struct qxl_device *qdev, uint32_t surface_id,
const struct qxl_rect *area)
{
+ unsigned surface_width = qxl_surface_width(qdev, surface_id);
+ unsigned surface_height = qxl_surface_height(qdev, surface_id);
+
+ if (area->left < 0 || area->top < 0 ||
+ area->right > surface_width || area->bottom > surface_height) {
+ qxl_io_log(qdev, "%s: not doing area update for "
+ "%d, (%d,%d,%d,%d)\n", surface_id, area->left,
+ area->top, area->right, area->bottom);
+ return;
+ }
qdev->ram_header->update_area = *area;
qdev->ram_header->update_surface = surface_id;
wait_for_io_cmd(qdev, 0, QXL_IO_UPDATE_AREA_ASYNC);
diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
index a15ed9da1df..25e97dce60c 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.h
+++ b/drivers/gpu/drm/qxl/qxl_drv.h
@@ -206,6 +206,8 @@ struct qxl_fb_work_item {
};
};
+#define QXL_MAX_SURFACES 8192
+
struct qxl_device {
struct device *dev;
struct drm_device *ddev;
@@ -232,6 +234,8 @@ struct qxl_device {
struct qxl_gem gem;
struct qxl_mode_info mode_info;
+ struct qxl_surface surfaces[QXL_MAX_SURFACES];
+
/*
* last created framebuffer with fb_create
* only used by debugfs dumbppm
@@ -288,6 +292,22 @@ struct qxl_device {
struct work_struct client_monitors_config_work;
};
+static inline unsigned
+qxl_surface_width(struct qxl_device *qdev, unsigned surface_id) {
+ return surface_id == 0 ? qdev->primary_width :
+ (surface_id < QXL_MAX_SURFACES &&
+ qdev->surfaces[surface_id].data != 0 ?
+ qdev->surfaces[surface_id].width : 0);
+}
+
+static inline unsigned
+qxl_surface_height(struct qxl_device *qdev, unsigned surface_id) {
+ return surface_id == 0 ? qdev->primary_height :
+ (surface_id < QXL_MAX_SURFACES &&
+ qdev->surfaces[surface_id].data != 0 ?
+ qdev->surfaces[surface_id].height : 0);
+}
+
/* forward declaration for QXL_INFO_IO */
void qxl_io_log(struct qxl_device *qdev, const char *fmt, ...);