diff --git a/src/bin/e_drm2.x b/src/bin/e_drm2.x index 8d620e000..6ef705814 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 3cdb746c0..f2991b8a8 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; + /* 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); - e_drm2_output_info_get(output, NULL, NULL, &ow, &oh, NULL); - pw += MAX(pw, ow); - ph = MAX(ph, oh); + 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) + { + printf("RRR: unconfigured screen: %s\n", s->info.name); + continue; + } + + 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_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 */ + } + } + } } + /* free(outputs); */ + /* free(crtcs); */ + 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; + 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("DRM2 RRR: set vsize: %ix%i\n", vw, vh); - - EINA_LIST_FOREACH(e_randr2->screens, ll, s) - { - Ecore_Drm2_Output_Mode *mode = NULL; - - if (!s->config.configured) continue; - - output = _drm2_output_find(outputs, s->info.name); - if (!output) continue; - - if (s->config.enabled) - mode = _drm2_mode_screen_find(s, output); - - if (s->config.priority > top_priority) - top_priority = s->config.priority; - - ecore_drm2_output_mode_set(output, mode, s->config.geom.x, - s->config.geom.y); - - /* TODO: cannot support rotations until we support planes - * and we cannot support planes until Atomic support is in */ - int orient = 0; - - 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; - - ecore_drm2_output_rotation_set(output, orient); - - if (s->config.priority == top_priority) - _drm2_output_primary_set(outputs, output); - - ecore_drm2_output_enabled_set(output, s->config.enabled); - - 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