summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Michael <cp.michael@samsung.com>2019-03-06 12:45:53 -0500
committerChristopher Michael <cp.michael@samsung.com>2019-03-19 08:27:58 -0400
commit6583ea934837de38cbc147877a708481a9dcaed2 (patch)
treec97a8b3f1bff95a1197658b3147d482cc3ed4e2a
parentfb23acf87417d2c97ad4a5914d742fbf0c8a00e1 (diff)
downloadenlightenment-devs/devilhorns/rotation.tar.gz
wl-drm: Refactor _drm2_randr_apply functiondevs/devilhorns/rotation
This patch refactors _drm2_randr_apply inside the wl_drm module in order to support multiple outputs and to fix issue of rotation not working ref T7690 Differential Revision: https://phab.enlightenment.org/D8117
-rw-r--r--src/bin/e_drm2.x29
-rw-r--r--src/modules/wl_drm/e_mod_main.c239
2 files changed, 190 insertions, 78 deletions
diff --git a/src/bin/e_drm2.x b/src/bin/e_drm2.x
index 8d620e0000..6ef7058144 100644
--- a/src/bin/e_drm2.x
+++ b/src/bin/e_drm2.x
@@ -13,6 +13,8 @@ void (*sym_ecore_drm2_device_free_120)(Ecore_Drm2_Device *device);
void (*sym_ecore_drm2_output_info_get_121)(Ecore_Drm2_Output *output, int *x, int *y, int *w, int *h, unsigned int *refresh);
Ecore_Drm2_Fb *(*sym_ecore_drm2_fb_create_120)(int fd, int width, int height, int depth, int bpp, unsigned int format);
Ecore_Drm2_Fb *(*sym_ecore_drm2_fb_create_121)(Ecore_Drm2_Device *dev, int width, int height, int depth, int bpp, unsigned int format);
+int (*sym_ecore_drm2_output_rotation_get_122)(Ecore_Drm2_Output *output);
+Eina_Bool (*sym_ecore_drm2_output_rotation_set_122)(Ecore_Drm2_Output *output, int rotation);
#define E_DRM2_EFL_VERSION_MINIMUM(MAJ, MIN, MIC) \
((eina_version->major > MAJ) || (eina_version->minor > MIN) ||\
@@ -30,6 +32,13 @@ e_drm2_compat_init(void)
}
e_drm2_lib = dlopen("libecore_drm2.so", RTLD_NOW | RTLD_LOCAL);
+
+ if (E_DRM2_EFL_VERSION_MINIMUM(1, 21, 99))
+ {
+ EDRM2SYM(ecore_drm2_output_rotation_get, 122);
+ EDRM2SYM(ecore_drm2_output_rotation_set, 122);
+ }
+
if (E_DRM2_EFL_VERSION_MINIMUM(1, 20, 99))
{
EDRM2SYM(ecore_drm2_device_open, 121);
@@ -112,4 +121,24 @@ e_drm2_fb_create(Ecore_Drm2_Device *device, int width, int height, int depth, in
return sym_ecore_drm2_fb_create_120(crude_hack_fd, width, height, depth, bpp, format);
}
+static int
+e_drm2_output_rotation_get(Ecore_Drm2_Output *output)
+{
+ if (E_DRM2_EFL_VERSION_MINIMUM(1, 21, 99))
+ {
+ return sym_ecore_drm2_output_rotation_get_122(output);
+ }
+ return 0;
+}
+
+static Eina_Bool
+e_drm2_output_rotation_set(Ecore_Drm2_Output *output, int rotation)
+{
+ if (E_DRM2_EFL_VERSION_MINIMUM(1, 21, 99))
+ {
+ return sym_ecore_drm2_output_rotation_set_122(output, rotation);
+ }
+ return EINA_FALSE;
+}
+
#undef E_DRM2_EFL_VERSION_MINIMUM
diff --git a/src/modules/wl_drm/e_mod_main.c b/src/modules/wl_drm/e_mod_main.c
index 3cdb746c0e..f2991b8a80 100644
--- a/src/modules/wl_drm/e_mod_main.c
+++ b/src/modules/wl_drm/e_mod_main.c
@@ -295,6 +295,9 @@ _drm2_randr_create(void)
Eina_Bool ok = EINA_FALSE;
Eina_Bool possible = EINA_FALSE;
+ if (!ecore_drm2_output_connected_get(output))
+ continue;
+
s = E_NEW(E_Randr2_Screen, 1);
if (!s) continue;
@@ -313,6 +316,7 @@ _drm2_randr_create(void)
s->id = malloc(strlen(s->info.name) + 1 + 1);
if (!s->id)
{
+ free(s->info.name);
free(s->info.screen);
free(s->info.edid);
free(s);
@@ -392,6 +396,8 @@ _drm2_randr_create(void)
if (ok)
{
+ int rotations;
+
if (!possible)
{
unsigned int refresh;
@@ -413,13 +419,13 @@ _drm2_randr_create(void)
s->config.geom.w, s->config.geom.h);
}
+ s->config.rotation = e_drm2_output_rotation_get(output);
+
s->info.can_rot_0 = EINA_FALSE;
s->info.can_rot_90 = EINA_FALSE;
s->info.can_rot_180 = EINA_FALSE;
s->info.can_rot_270 = EINA_FALSE;
- int rotations;
-
rotations =
ecore_drm2_output_supported_rotations_get(output);
@@ -520,106 +526,183 @@ _drm2_output_primary_set(const Eina_List *outputs, Ecore_Drm2_Output *output)
}
}
+static Eina_Bool
+_drm2_rotation_exists(Ecore_Drm2_Output *output, int rot)
+{
+ int rots;
+
+ rots = ecore_drm2_output_supported_rotations_get(output);
+ if (rots >= 0)
+ {
+ if ((rot == 0) && (rots & ECORE_DRM2_ROTATION_NORMAL))
+ return EINA_TRUE;
+ if ((rot == 90) && (rots & ECORE_DRM2_ROTATION_90))
+ return EINA_TRUE;
+ if ((rot == 180) && (rots & ECORE_DRM2_ROTATION_180))
+ return EINA_TRUE;
+ if ((rot == 270) && (rots & ECORE_DRM2_ROTATION_270))
+ return EINA_TRUE;
+ }
+
+ return EINA_FALSE;
+}
+
static void
_drm2_randr_apply(void)
{
- const Eina_List *l;
- Eina_List *ll;
- E_Randr2_Screen *s;
Ecore_Drm2_Device *dev;
- const Eina_List *outputs;
- Ecore_Drm2_Output *output;
- int minw, minh, maxw, maxh;
- int ow = 0, oh = 0;
- int pw = 0, ph = 0;
- int vw = 0, vh = 0;
+ Ecore_Drm2_Output **outconf, *out;
int nw = 0, nh = 0;
- int top_priority = 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;
- outputs = ecore_drm2_outputs_get(dev);
- if (!outputs) return;
-
- ecore_drm2_device_screen_size_range_get(dev, &minw, &minh, &maxw, &maxh);
- printf("DRM2 RRR: size range: %ix%i -> %ix%i\n", minw, minh, maxw, maxh);
-
nw = e_randr2->w;
nh = e_randr2->h;
- /* get virtual size */
- EINA_LIST_FOREACH(outputs, l, output)
- {
- if (!ecore_drm2_output_connected_get(output)) continue;
- if (!ecore_drm2_output_enabled_get(output)) continue;
- if (ecore_drm2_output_cloned_get(output)) continue;
-
- e_drm2_output_info_get(output, NULL, NULL, &ow, &oh, NULL);
- pw += MAX(pw, ow);
- ph = MAX(ph, oh);
- }
-
- if (nw > maxw) nw = maxw;
- if (nh > maxh) nh = maxh;
- if (nw < minw) nw = minw;
- if (nh < minh) nh = minh;
- vw = nw;
- vh = nh;
- if (nw < pw) vw = pw;
- if (nh < ph) vh = ph;
+ /* 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);
- printf("DRM2 RRR: set vsize: %ix%i\n", vw, vh);
+ crtcs = ecore_drm2_device_crtcs_get(dev, &num_crtcs);
+ outputs = ecore_drm2_outputs_get(dev);
- EINA_LIST_FOREACH(e_randr2->screens, ll, s)
+ if ((crtcs) && (outputs))
{
- Ecore_Drm2_Output_Mode *mode = NULL;
-
- if (!s->config.configured) continue;
-
- output = _drm2_output_find(outputs, s->info.name);
- if (!output) continue;
+ E_Randr2_Screen *s;
+ Eina_List *l;
+ int top_priority = 0, i;
- if (s->config.enabled)
- mode = _drm2_mode_screen_find(s, output);
+ 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 *));
- if (s->config.priority > top_priority)
- top_priority = s->config.priority;
+ /* decide which outputs gets which crtcs */
+ EINA_LIST_FOREACH(e_randr2->screens, l, s)
+ {
+ printf("RRR: find output for '%s'\n", s->info.name);
- ecore_drm2_output_mode_set(output, mode, s->config.geom.x,
- s->config.geom.y);
+ if (!s->config.configured)
+ {
+ printf("RRR: unconfigured screen: %s\n", s->info.name);
+ continue;
+ }
- /* TODO: cannot support rotations until we support planes
- * and we cannot support planes until Atomic support is in */
- int orient = 0;
+ 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;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
- if (s->config.rotation == 0)
- orient = ECORE_DRM2_ROTATION_NORMAL;
- else if (s->config.rotation == 90)
- orient = ECORE_DRM2_ROTATION_90;
- else if (s->config.rotation == 180)
- orient = ECORE_DRM2_ROTATION_180;
- else if (s->config.rotation == 270)
- orient = ECORE_DRM2_ROTATION_270;
+ numout = 0;
+ for (i = 0; i < num_crtcs; i++)
+ if (outconf[i]) numout++;
- ecore_drm2_output_rotation_set(output, orient);
+ 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_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);
+
+ e_drm2_output_rotation_set(outconf[i], orient);
+
+ ecore_evas_rotation_with_resize_set(e_comp->ee,
+ screenconf[i]->config.rotation);
+ }
+ else
+ {
+ printf("RRR: crtc off: %i\n", i);
+ /* FIXME: Need new drm2 API to disable crtc...
+ * one which Does Not Take an Output as param */
+ }
+ }
+ }
+ }
- if (s->config.priority == top_priority)
- _drm2_output_primary_set(outputs, output);
+ /* free(outputs); */
+ /* free(crtcs); */
- ecore_drm2_output_enabled_set(output, s->config.enabled);
+ 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_rotation_set(dev, ecore_evas_rotation_get(e_comp->ee));
- printf("\tDRM2 RRR: Mode\n");
- printf("\t\tDRM2 RRR: Geom: %d %d %dx%d\n",
- s->config.geom.x, s->config.geom.y,
- s->config.mode.w, s->config.mode.h);
- printf("\t\tDRM2 RRR: Refresh: %f\n", s->config.mode.refresh);
- printf("\t\tDRM2 RRR: Preferred: %d\n", s->config.mode.preferred);
- printf("\tDRM2 RRR: Rotation: %d\n", s->config.rotation);
- printf("\tDRM2 RRR: Relative Mode: %d\n", s->config.relative.mode);
- printf("\tDRM2 RRR: Relative To: %s\n", s->config.relative.to);
- printf("\tDRM2 RRR: Align: %f\n", s->config.relative.align);
- }
+ if (!e_randr2_cfg->ignore_hotplug_events)
+ e_randr2_screen_refresh_queue(EINA_FALSE);
}
static void