wl_drm: refactor _drm2_randr_apply function to support multi-output

This patch refactors the drm2_randr_apply function in order to support
clone & extended modes for multiple outputs. This is modeled closely
around the x11 randr apply code.

Signed-off-by: Chris Michael <cp.michael@samsung.com>
This commit is contained in:
Chris Michael 2018-03-29 09:53:54 -04:00 committed by Christopher Michael
parent 9b83f001a3
commit 0525154d25
1 changed files with 161 additions and 0 deletions

View File

@ -553,12 +553,14 @@ _drm2_rotation_exists(Ecore_Drm2_Output *output, int rot)
int rots;
rots = ecore_drm2_output_supported_rotations_get(output);
printf("RRR: DRM2 ..... rots for %p rots=%x input=%x\n", output, rots, rot);
// hack for ... broken drivers that don't say anything about rotations
if (!(rots &
(ECORE_DRM2_ROTATION_NORMAL | ECORE_DRM2_ROTATION_90 |
ECORE_DRM2_ROTATION_180 | ECORE_DRM2_ROTATION_270)))
rots |= ECORE_DRM2_ROTATION_NORMAL;
if (rots >= 0)
{
if ((rot == 0) && (rots & ECORE_DRM2_ROTATION_NORMAL))
@ -578,6 +580,165 @@ _drm2_rotation_exists(Ecore_Drm2_Output *output, int rot)
static void
_drm2_randr_apply(void)
{
Ecore_Drm2_Device *dev;
Ecore_Drm2_Output **outconf, *out;
int nw = 0, nh = 0;
int minw, minh, maxw, maxh;
unsigned int *crtcs = NULL;
int num_crtcs = 0, numout = 0;
const Eina_List *outputs = NULL;
E_Randr2_Screen **screenconf;
/* get drm device */
dev = ecore_evas_data_get(e_comp->ee, "device");
if (!dev) return;
nw = e_randr2->w;
nh = e_randr2->h;
/* get screen size range */
ecore_drm2_device_screen_size_range_get(dev, &minw, &minh, &maxw, &maxh);
printf("RRR: size range: %ix%i -> %ix%i\n", minw, minh, maxw, maxh);
crtcs = ecore_drm2_device_crtcs_get(dev, &num_crtcs);
outputs = ecore_drm2_outputs_get(dev);
if ((crtcs) && (outputs))
{
E_Randr2_Screen *s;
Eina_List *l;
int top_priority = 0, i;
outconf = alloca(num_crtcs * sizeof(Ecore_Drm2_Output *));
screenconf = alloca(num_crtcs * sizeof(E_Randr2_Screen *));
memset(outconf, 0, num_crtcs * sizeof(Ecore_Drm2_Output *));
memset(screenconf, 0, num_crtcs * sizeof(E_Randr2_Screen *));
/* decide which outputs gets which crtcs */
EINA_LIST_FOREACH(e_randr2->screens, l, s)
{
printf("RRR: find output for '%s'\n", s->info.name);
if (s->config.configured)
{
out = _drm2_output_find(outputs, s->info.name);
if (out)
{
printf("RRR: enabled: %i\n", s->config.enabled);
if (s->config.enabled)
{
if (s->config.priority > top_priority)
top_priority = s->config.priority;
for (i = 0; i < num_crtcs; i++)
{
if (!outconf[i])
{
printf("RRR: crtc slot empty: %i\n", i);
if (ecore_drm2_output_possible_crtc_get(out, crtcs[i]))
{
if (_drm2_rotation_exists(out, s->config.rotation))
{
printf("RRR: assign slot out: %p\n", out);
outconf[i] = out;
screenconf[i] = s;
break;
}
}
}
}
}
}
}
}
numout = 0;
for (i = 0; i < num_crtcs; i++)
if (outconf[i]) numout++;
if (numout)
{
for (i = 0; i < num_crtcs; i++)
{
if (outconf[i])
{
Ecore_Drm2_Output_Mode *mode;
Ecore_Drm2_Rotation orient = ECORE_DRM2_ROTATION_NORMAL;
mode = _drm2_mode_screen_find(screenconf[i], outconf[i]);
if (screenconf[i]->config.rotation == 0)
orient = ECORE_DRM2_ROTATION_NORMAL;
else if (screenconf[i]->config.rotation == 90)
orient = ECORE_DRM2_ROTATION_90;
else if (screenconf[i]->config.rotation == 180)
orient = ECORE_DRM2_ROTATION_180;
else if (screenconf[i]->config.rotation == 270)
orient = ECORE_DRM2_ROTATION_270;
printf("RRR: crtc on: %i = '%s' @ %i %i - %ix%i orient %i mode %p out %p\n",
i, screenconf[i]->info.name,
screenconf[i]->config.geom.x,
screenconf[i]->config.geom.y,
screenconf[i]->config.geom.w,
screenconf[i]->config.geom.h,
orient, mode, outconf[i]);
ecore_drm2_output_mode_set(outconf[i], mode,
screenconf[i]->config.geom.x,
screenconf[i]->config.geom.y);
ecore_drm2_output_rotation_set(outconf[i], orient);
ecore_drm2_output_relative_to_set(outconf[i],
screenconf[i]->config.relative.to);
ecore_drm2_output_relative_mode_set(outconf[i],
screenconf[i]->config.relative.mode);
if (screenconf[i]->config.priority == top_priority)
{
_drm2_output_primary_set(outputs, outconf[i]);
top_priority = -1;
}
ecore_drm2_output_enabled_set(outconf[i],
screenconf[i]->config.enabled);
if ((screenconf[i]->config.relative.to) &&
(screenconf[i]->config.relative.mode ==
E_RANDR2_RELATIVE_CLONE))
{
Ecore_Drm2_Output *clone;
clone = _drm2_output_find(outputs,
screenconf[i]->config.relative.to);
ecore_evas_output_clone_set(e_comp->ee, outconf[i],
clone);
}
else
ecore_evas_output_clone_set(e_comp->ee, outconf[i],
NULL);
/* ecore_drm2_output_cloned_set(dev, outconf[i], EINA_TRUE); */
/* else */
/* ecore_drm2_output_cloned_set(dev, outconf[i], EINA_FALSE); */
}
else
{
printf("RRR: crtc off: %i\n", i);
}
}
}
}
/* free(outputs); */
/* free(crtcs); */
if (nw > maxw) nw = maxw;
if (nh > maxh) nh = maxh;
if (nw < minw) nw = minw;
if (nh < minh) nh = minh;
printf("RRR: set vsize: %ix%i\n", nw, nh);
ecore_drm2_device_calibrate(dev, nw, nh);
ecore_drm2_device_pointer_max_set(dev, nw, nh);
ecore_drm2_device_pointer_warp(dev, nw / 2, nh / 2);
}
static void