summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Levy <alevy@redhat.com>2012-08-05 10:25:58 +0200
committerAlon Levy <alevy@redhat.com>2012-10-23 18:46:58 +0200
commit7235c312c436ed2b8a1d1abb9d30b589479f5797 (patch)
tree233bd1ab72f0d9bdd96e5627fcabac7c78f24fbd
parent0dbb62d61ba8a3bd03da83ac8155e53242128e52 (diff)
monitors_config and update_area kms/ums split
-rw-r--r--src/qxl.h2
-rw-r--r--src/qxl_driver.c143
-rw-r--r--src/qxl_surface.c49
3 files changed, 128 insertions, 66 deletions
diff --git a/src/qxl.h b/src/qxl.h
index cd555e5..f458ac2 100644
--- a/src/qxl.h
+++ b/src/qxl.h
@@ -535,7 +535,7 @@ static inline void qxl_mem_unverifiable(struct qxl_mem *mem) {}
/*
* I/O port commands
*/
-void qxl_update_area(qxl_screen_t *qxl);
+void qxl_io_update_area(qxl_screen_t *qxl);
void qxl_io_flush_surfaces(qxl_screen_t *qxl);
void qxl_io_destroy_all_surfaces (qxl_screen_t *qxl);
diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index 9aac8f3..c5d19f4 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -170,7 +170,7 @@ qxl_wait_for_display_interrupt (qxl_screen_t *qxl)
#endif
void
-qxl_update_area (qxl_screen_t *qxl)
+qxl_io_update_area (qxl_screen_t *qxl)
{
#ifndef XSPICE
if (qxl->pci->revision >= 3)
@@ -429,7 +429,7 @@ qxl_io_monitors_config_async (qxl_screen_t *qxl)
#define MAX_MONITORS_NUM 16
static void
-qxl_allocate_monitors_config (qxl_screen_t *qxl)
+qxl_ums_allocate_monitors_config (qxl_screen_t *qxl)
{
int size = sizeof (QXLMonitorsConfig) + sizeof (QXLHead) * MAX_MONITORS_NUM;
@@ -442,6 +442,25 @@ qxl_allocate_monitors_config (qxl_screen_t *qxl)
memset (qxl->monitors_config, 0, size);
}
+static void
+qxl_kms_allocate_monitors_config(qxl_screen_t *qxl)
+{
+ ErrorF("%s: unimplemented monitors_config sending TODO\n", __func__);
+ if (qxl->monitors_config)
+ return;
+ qxl->monitors_config = malloc(sizeof(*qxl->monitors_config));
+}
+
+static void
+qxl_allocate_monitors_config(qxl_screen_t *qxl)
+{
+ if (is_kms(qxl)) {
+ qxl_kms_allocate_monitors_config(qxl);
+ } else {
+ qxl_ums_allocate_monitors_config(qxl);
+ }
+}
+
static uint64_t
qxl_garbage_collect_internal (qxl_screen_t *qxl, uint64_t id)
{
@@ -1088,7 +1107,7 @@ qxl_kms_resize_primary_to_virtual (qxl_screen_t *qxl)
{
struct QXLMode *pm = &qxl->primary_mode;
- ErrorF("unimplemented kms resize to %dx%d\n",
+ ErrorF("null (unimplemented) kms resize to %dx%d\n",
qxl->virtual_x, qxl->virtual_y);
pm->id = 0x435;
pm->x_res = qxl->virtual_x;
@@ -1253,16 +1272,33 @@ check_crtc (qxl_screen_t *qxl)
}
static void
-qxl_update_monitors_config (qxl_screen_t *qxl)
+qxl_ums_update_monitors_config (qxl_screen_t *qxl)
+{
+ QXLRam *ram = get_ram_header (qxl);
+ /* initialize when actually used, memslots should be initialized by now */
+ if (ram->monitors_config == 0)
+ ram->monitors_config = physical_address (qxl, qxl->monitors_config,
+ qxl->main_mem_slot);
+
+ qxl_io_monitors_config_async (qxl);
+}
+
+static void
+qxl_kms_update_monitors_config (qxl_screen_t *qxl)
+{
+ // TODO? or have KMS do this by itself? can always add an ioctl.
+}
+
+static void
+qxl_update_monitors_config(qxl_screen_t *qxl)
{
int i;
QXLHead *head;
xf86CrtcPtr crtc;
qxl_output_private *qxl_output;
- QXLRam * ram = get_ram_header (qxl);
-
+
check_crtc (qxl);
-
+
qxl->monitors_config->count = 0;
qxl->monitors_config->max_allowed = qxl->num_heads;
for (i = 0 ; i < qxl->num_heads; ++i)
@@ -1290,14 +1326,10 @@ qxl_update_monitors_config (qxl_screen_t *qxl)
qxl_output->status = XF86OutputStatusConnected;
}
}
- /* initialize when actually used, memslots should be initialized by now */
- if (ram->monitors_config == 0)
- {
- ram->monitors_config = physical_address (qxl, qxl->monitors_config,
- qxl->main_mem_slot);
- }
-
- qxl_io_monitors_config_async (qxl);
+ if (is_kms (qxl))
+ qxl_kms_update_monitors_config (qxl);
+ else
+ qxl_ums_update_monitors_config (qxl);
}
static Bool
@@ -1313,7 +1345,7 @@ crtc_set_mode_major (xf86CrtcPtr crtc, DisplayModePtr mode,
ErrorF ("%s: not allowing crtc 0 disablement\n", __func__);
return FALSE;
}
-
+
crtc->mode = *mode;
crtc->x = x;
crtc->y = y;
@@ -1322,7 +1354,7 @@ crtc_set_mode_major (xf86CrtcPtr crtc, DisplayModePtr mode,
crtc->transformPresent = FALSE;
#endif
qxl_output_edid_set (crtc_private->output, crtc_private->head, mode);
-
+
return TRUE;
}
@@ -1396,18 +1428,16 @@ qxl_create_screen_resources (ScreenPtr pScreen)
set_surface (pPixmap, qxl->primary);
/* HACK - I don't want to enable any crtcs other then the first at the beginning */
- for (i = 1; i < qxl->num_heads; ++i)
- {
- qxl_output_private *private;
-
- qxl->crtcs[i]->enabled = 0;
- private = qxl->outputs[i]->driver_private;
- private->status = XF86OutputStatusDisconnected;
+ for (i = 1; i < qxl->num_heads; ++i) {
+ qxl_output_private *private;
+ qxl->crtcs[i]->enabled = 0;
+ private = qxl->outputs[i]->driver_private;
+ private->status = XF86OutputStatusDisconnected;
}
-
+
+ qxl_allocate_monitors_config (qxl);
qxl_create_desired_modes (qxl);
qxl_update_edid (qxl);
-
return TRUE;
}
@@ -1969,7 +1999,7 @@ qxl_screen_init (SCREEN_INIT_ARGS_DECL)
if (!qxl_map_memory (qxl, pScrn->scrnIndex))
return FALSE;
} else {
- ErrorF("KMS HACK: setting screen to 640x480");
+ ErrorF("KMS HACK: setting screen to 640x480\n");
pScrn->currentMode->HDisplay = 640;
pScrn->currentMode->VDisplay = 480;
pScrn->virtualY = 480;
@@ -2512,38 +2542,37 @@ qxl_init_randr (ScrnInfoPtr pScrn, qxl_screen_t *qxl)
/* CHECKME: This is actually redundant, it's overwritten by a later call via
* xf86InitialConfiguration */
xf86CrtcSetSizeRange (pScrn, 320, 200, 8192, 8192);
-
+
qxl->crtcs = xnfcalloc (sizeof (xf86CrtcPtr), qxl->num_heads);
qxl->outputs = xnfcalloc (sizeof (xf86OutputPtr), qxl->num_heads);
-
- for (i = 0 ; i < qxl->num_heads; ++i)
- {
- qxl->crtcs[i] = xf86CrtcCreate (pScrn, &qxl_crtc_funcs);
- if (!qxl->crtcs[i])
- xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "failed to create Crtc %d", i);
-
- qxl_crtc = xnfcalloc (sizeof (qxl_crtc_private), 1);
- qxl->crtcs[i]->driver_private = qxl_crtc;
- qxl_crtc->head = i;
- qxl_crtc->qxl = qxl;
- snprintf (name, sizeof (name), "qxl-%d", i);
- qxl->outputs[i] = output = xf86OutputCreate (pScrn, &qxl_output_funcs, name);
- if (!output)
- xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "failed to create Output %d", i);
-
- output->possible_crtcs = (1 << i); /* bitrange of allowed outputs - do a 1:1 */
- output->possible_clones = 0; /* TODO: not? */
- qxl_output = xnfcalloc (sizeof (qxl_output_private), 1);
- output->driver_private = qxl_output;
- qxl_output->head = i;
- qxl_output->qxl = qxl;
- qxl_output->status = XF86OutputStatusConnected;
- qxl_crtc->output = output;
- }
-
- qxl->virtual_x = 1024;
- qxl->virtual_y = 768;
-
+
+ for (i = 0 ; i < qxl->num_heads; ++i) {
+ qxl->crtcs[i] = xf86CrtcCreate (pScrn, &qxl_crtc_funcs);
+ if (!qxl->crtcs[i])
+ xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "failed to create Crtc %d", i);
+
+ qxl_crtc = xnfcalloc (sizeof(qxl_crtc_private), 1);
+ qxl->crtcs[i]->driver_private = qxl_crtc;
+ qxl_crtc->head = i;
+ qxl_crtc->qxl = qxl;
+ snprintf (name, sizeof(name), "qxl-%d", i);
+ qxl->outputs[i] = output = xf86OutputCreate (pScrn, &qxl_output_funcs, name);
+ if (!output)
+ xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "failed to create Output %d", i);
+
+ output->possible_crtcs = (1 << i); /* bitrange of allowed outputs - do a 1:1 */
+ output->possible_clones = 0; /* TODO: not? */
+ qxl_output = xnfcalloc (sizeof (qxl_output_private), 1);
+ output->driver_private = qxl_output;
+ qxl_output->head = i;
+ qxl_output->qxl = qxl;
+ qxl_output->status = XF86OutputStatusConnected;
+ qxl_crtc->output = output;
+ }
+
+ qxl->virtual_x = 640;
+ qxl->virtual_y = 480;
+
pScrn->display->virtualX = qxl->virtual_x;
pScrn->display->virtualY = qxl->virtual_y;
diff --git a/src/qxl_surface.c b/src/qxl_surface.c
index 13f193b..ba1fee2 100644
--- a/src/qxl_surface.c
+++ b/src/qxl_surface.c
@@ -47,6 +47,9 @@
#include "config.h"
#endif
+#include <xf86drm.h>
+#include <libdrm/qxl_drm.h>
+
#include "qxl.h"
#ifdef DEBUG_SURFACE_LIFECYCLE
@@ -524,7 +527,9 @@ make_drawable (qxl_screen_t *qxl, int surface, uint8_t type,
if (rect)
drawable->bbox = *rect;
- drawable->mm_time = qxl->rom->mm_clock;
+ if (!is_kms(qxl)) {
+ drawable->mm_time = qxl->rom->mm_clock;
+ }
return drawable;
}
@@ -895,7 +900,7 @@ qxl_surface_flush (qxl_surface_t *surface)
/* access */
static void
-download_box_no_update (qxl_surface_t *surface, int x1, int y1, int x2, int y2)
+qxl_download_box_no_update (qxl_surface_t *surface, int x1, int y1, int x2, int y2)
{
pixman_image_composite (PIXMAN_OP_SRC,
surface->dev_image,
@@ -905,7 +910,7 @@ download_box_no_update (qxl_surface_t *surface, int x1, int y1, int x2, int y2)
}
static void
-download_box (qxl_surface_t *surface, int x1, int y1, int x2, int y2)
+qxl_ums_download_box (qxl_surface_t *surface, int x1, int y1, int x2, int y2)
{
struct QXLRam *ram_header = get_ram_header (surface->cache->qxl);
@@ -916,9 +921,37 @@ download_box (qxl_surface_t *surface, int x1, int y1, int x2, int y2)
ram_header->update_surface = surface->id;
- qxl_update_area(surface->cache->qxl);
+ qxl_io_update_area(surface->cache->qxl);
+}
- download_box_no_update(surface, x1, y1, x2, y2);
+static void
+qxl_kms_download_box (qxl_surface_t *surface, int x1, int y1, int x2, int y2)
+{
+ int ret;
+ struct drm_qxl_update_area update_area = {
+ .surface_id = surface->id,
+ .left = x1,
+ .top = y1,
+ .right = x2,
+ .bottom = y2
+ };
+
+ ret = drmIoctl(surface->cache->qxl->drm_fd,
+ DRM_IOCTL_QXL_UPDATE_AREA, &update_area);
+ if (ret) {
+ fprintf(stderr, "error doing QXL_UPDATE_AREA\n");
+ }
+}
+
+static void
+qxl_download_box (qxl_surface_t *surface, int x1, int y1, int x2, int y2)
+{
+ if (is_kms(surface->cache->qxl)) {
+ qxl_kms_download_box(surface, x1, y1, x2, y2);
+ } else {
+ qxl_ums_download_box(surface, x1, y1, x2, y2);
+ }
+ qxl_download_box_no_update(surface, x1, y1, x2, y2);
}
Bool
@@ -951,14 +984,14 @@ qxl_surface_prepare_access (qxl_surface_t *surface,
{
while (n_boxes--)
{
- download_box (surface, boxes->x1, boxes->y1, boxes->x2, boxes->y2);
+ qxl_download_box (surface, boxes->x1, boxes->y1, boxes->x2, boxes->y2);
boxes++;
}
}
else
{
- download_box (
+ qxl_download_box (
surface,
new.extents.x1, new.extents.y1, new.extents.x2, new.extents.y2);
}
@@ -1119,7 +1152,7 @@ qxl_surface_cache_evacuate_all (surface_cache_t *cache)
width = pixman_image_get_width (s->host_image);
height = pixman_image_get_height (s->host_image);
- download_box (s, 0, 0, width, height);
+ qxl_download_box (s, 0, 0, width, height);
evacuated->image = s->host_image;
evacuated->pixmap = s->pixmap;