devilhorns pushed a commit to branch feature/wayland/multi-output. http://git.enlightenment.org/core/enlightenment.git/commit/?id=2ed0a07bc9a89780047df543f7c4afe38d1d8e9b
commit 2ed0a07bc9a89780047df543f7c4afe38d1d8e9b Author: Chris Michael <[email protected]> Date: Thu Mar 29 09:53:54 2018 -0400 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 <[email protected]> --- src/modules/wl_drm/e_mod_main.c | 179 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) diff --git a/src/modules/wl_drm/e_mod_main.c b/src/modules/wl_drm/e_mod_main.c index 80285660d..84667ce96 100644 --- a/src/modules/wl_drm/e_mod_main.c +++ b/src/modules/wl_drm/e_mod_main.c @@ -523,10 +523,189 @@ _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) { + 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 --
