summaryrefslogtreecommitdiff
path: root/src/sna/sna_display.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-08-29 23:00:05 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2013-08-30 08:57:25 +0100
commit68d139388a2a037347fa5c838391e67e006793ee (patch)
treefcac6d4c98fd88b1c9bd24483972da6a95cbd739 /src/sna/sna_display.c
parent92a43caab96e7f49c541fb999b75925914d9981a (diff)
sna: Allow user specification of number of VirtualHeads
Previously, we instantiated a fake output in case we had a machine with no output. (For certain server-class products.) The Bumblee project were also doing something very similar in order to fake an extended desktop on the Intel igfx and copy portions onto a discrete GPU. (The preferred method for doing this upstream is through the use of PRIME). As the code is very similar, we can support both use-cases simultaneously. This adds the option: Section "Device" Driver "intel" Option "VirtualHeads" "<count>" EndSection to allow the user to specify an additional set of fake outputs, which can then be controlled using xrandr. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna/sna_display.c')
-rw-r--r--src/sna/sna_display.c62
1 files changed, 46 insertions, 16 deletions
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index da3475ff..aa445ae3 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -2758,8 +2758,15 @@ sna_mode_resize(ScrnInfoPtr scrn, int width, int height)
"resizing framebuffer to %dx%d\n",
width, height);
- for (i = 0; i < xf86_config->num_crtc; i++)
- sna_crtc_disable_shadow(sna, to_sna_crtc(xf86_config->crtc[i]));
+ for (i = 0; i < xf86_config->num_crtc; i++) {
+ struct sna_crtc *crtc;
+
+ crtc = to_sna_crtc(xf86_config->crtc[i]);
+ if (crtc == NULL)
+ continue;
+
+ sna_crtc_disable_shadow(sna, crtc);
+ }
assert(sna->mode.shadow_active == 0);
assert(sna->mode.shadow_damage == NULL);
assert(sna->mode.shadow == NULL);
@@ -2778,7 +2785,7 @@ sna_mode_resize(ScrnInfoPtr scrn, int width, int height)
for (i = 0; i < xf86_config->num_crtc; i++) {
xf86CrtcPtr crtc = xf86_config->crtc[i];
- if (!crtc->enabled)
+ if (!crtc->enabled || to_sna_crtc(crtc) == NULL)
continue;
if (!sna_crtc_set_mode_major(crtc,
@@ -2818,8 +2825,8 @@ static int do_page_flip(struct sna *sna, struct kgem_bo *bo,
struct drm_mode_crtc_page_flip arg;
DBG(("%s: crtc %d active? %d\n",
- __FUNCTION__, i, crtc->bo != NULL));
- if (crtc->bo == NULL)
+ __FUNCTION__, i, crtc && crtc->bo));
+ if (crtc == NULL || crtc->bo == NULL)
continue;
arg.crtc_id = crtc->id;
@@ -3019,6 +3026,9 @@ static bool sna_probe_initial_configuration(struct sna *sna)
struct drm_mode_crtc mode;
uint16_t *gamma;
+ if (sna_crtc == NULL)
+ continue;
+
crtc->enabled = FALSE;
crtc->desiredMode.status = MODE_NOMODE;
@@ -3088,6 +3098,9 @@ static bool sna_probe_initial_configuration(struct sna *sna)
xf86OutputPtr output = config->output[i];
uint32_t crtc_id;
+ if (to_sna_output(output) == NULL)
+ continue;
+
crtc_id = (uintptr_t)output->crtc;
output->crtc = NULL;
@@ -3189,6 +3202,7 @@ sna_crtc_config_notify(ScreenPtr screen)
bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna)
{
struct sna_mode *mode = &sna->mode;
+ int num_fake = 0;
int i;
if (sna->flags & SNA_IS_HOSTED) {
@@ -3196,6 +3210,9 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna)
return true;
}
+ if (!xf86GetOptValInteger(sna->Options, OPTION_VIRTUAL, &num_fake))
+ num_fake = 0;
+
mode->kmode = drmModeGetResources(sna->kgem.fd);
if (mode->kmode) {
xf86CrtcConfigInit(scrn, &sna_mode_funcs);
@@ -3211,17 +3228,20 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna)
if (!xf86IsEntityShared(scrn->entityList[0]))
sna_mode_compute_possible_clones(scrn);
-
- sna_setup_provider(scrn);
} else {
- if (!sna_mode_fake_init(sna))
- return false;
+ if (num_fake == 0)
+ num_fake = 1;
}
set_size_range(sna);
+ if (!sna_mode_fake_init(sna, num_fake))
+ return false;
+
if (!sna_probe_initial_configuration(sna))
xf86InitialConfiguration(scrn, TRUE);
+
+ sna_setup_provider(scrn);
return scrn->modes != NULL;
}
@@ -3241,8 +3261,15 @@ sna_mode_close(struct sna *sna)
if (sna->flags & SNA_IS_HOSTED)
return;
- for (i = 0; i < xf86_config->num_crtc; i++)
- sna_crtc_disable_shadow(sna, to_sna_crtc(xf86_config->crtc[i]));
+ for (i = 0; i < xf86_config->num_crtc; i++) {
+ struct sna_crtc *crtc;
+
+ crtc = to_sna_crtc(xf86_config->crtc[i]);
+ if (crtc == NULL)
+ continue;
+
+ sna_crtc_disable_shadow(sna, crtc);
+ }
}
void
@@ -3567,7 +3594,8 @@ sna_wait_for_scanline(struct sna *sna,
int y1, y2, pipe;
bool ret;
- assert(crtc);
+ assert(crtc != NULL);
+ assert(to_sna_crtc(crtc) != NULL);
assert(to_sna_crtc(crtc)->bo != NULL);
assert(pixmap == sna->front);
@@ -3930,7 +3958,7 @@ void sna_mode_redisplay(struct sna *sna)
struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
RegionRec damage;
- if (!sna_crtc->shadow)
+ if (sna_crtc == NULL || !sna_crtc->shadow)
continue;
assert(crtc->enabled);
@@ -3953,7 +3981,9 @@ void sna_mode_redisplay(struct sna *sna)
struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
RegionRec damage;
- if (!sna_crtc->shadow || sna_crtc->bo == sna->mode.shadow)
+ if (sna_crtc == NULL ||
+ !sna_crtc->shadow ||
+ sna_crtc->bo == sna->mode.shadow)
continue;
assert(crtc->enabled);
@@ -3987,8 +4017,8 @@ void sna_mode_redisplay(struct sna *sna)
struct drm_mode_crtc_page_flip arg;
DBG(("%s: crtc %d [%d, pipe=%d] active? %d\n",
- __FUNCTION__, i, crtc->id, crtc->pipe, crtc->bo != NULL));
- if (crtc->bo != old)
+ __FUNCTION__, i, crtc->id, crtc->pipe, crtc && crtc->bo));
+ if (crtc == NULL || crtc->bo != old)
continue;
assert(config->crtc[i]->enabled);