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)
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 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);
13void (*sym_ecore_drm2_output_info_get_121)(Ecore_Drm2_Output *output, int *x, int *y, int *w, int *h, unsigned int *refresh); 13void (*sym_ecore_drm2_output_info_get_121)(Ecore_Drm2_Output *output, int *x, int *y, int *w, int *h, unsigned int *refresh);
14Ecore_Drm2_Fb *(*sym_ecore_drm2_fb_create_120)(int fd, int width, int height, int depth, int bpp, unsigned int format); 14Ecore_Drm2_Fb *(*sym_ecore_drm2_fb_create_120)(int fd, int width, int height, int depth, int bpp, unsigned int format);
15Ecore_Drm2_Fb *(*sym_ecore_drm2_fb_create_121)(Ecore_Drm2_Device *dev, int width, int height, int depth, int bpp, unsigned int format); 15Ecore_Drm2_Fb *(*sym_ecore_drm2_fb_create_121)(Ecore_Drm2_Device *dev, int width, int height, int depth, int bpp, unsigned int format);
16int (*sym_ecore_drm2_output_rotation_get_122)(Ecore_Drm2_Output *output);
17Eina_Bool (*sym_ecore_drm2_output_rotation_set_122)(Ecore_Drm2_Output *output, int rotation);
16 18
17#define E_DRM2_EFL_VERSION_MINIMUM(MAJ, MIN, MIC) \ 19#define E_DRM2_EFL_VERSION_MINIMUM(MAJ, MIN, MIC) \
18 ((eina_version->major > MAJ) || (eina_version->minor > MIN) ||\ 20 ((eina_version->major > MAJ) || (eina_version->minor > MIN) ||\
@@ -30,6 +32,13 @@ e_drm2_compat_init(void)
30 } 32 }
31 33
32 e_drm2_lib = dlopen("libecore_drm2.so", RTLD_NOW | RTLD_LOCAL); 34 e_drm2_lib = dlopen("libecore_drm2.so", RTLD_NOW | RTLD_LOCAL);
35
36 if (E_DRM2_EFL_VERSION_MINIMUM(1, 21, 99))
37 {
38 EDRM2SYM(ecore_drm2_output_rotation_get, 122);
39 EDRM2SYM(ecore_drm2_output_rotation_set, 122);
40 }
41
33 if (E_DRM2_EFL_VERSION_MINIMUM(1, 20, 99)) 42 if (E_DRM2_EFL_VERSION_MINIMUM(1, 20, 99))
34 { 43 {
35 EDRM2SYM(ecore_drm2_device_open, 121); 44 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
112 return sym_ecore_drm2_fb_create_120(crude_hack_fd, width, height, depth, bpp, format); 121 return sym_ecore_drm2_fb_create_120(crude_hack_fd, width, height, depth, bpp, format);
113} 122}
114 123
124static int
125e_drm2_output_rotation_get(Ecore_Drm2_Output *output)
126{
127 if (E_DRM2_EFL_VERSION_MINIMUM(1, 21, 99))
128 {
129 return sym_ecore_drm2_output_rotation_get_122(output);
130 }
131 return 0;
132}
133
134static Eina_Bool
135e_drm2_output_rotation_set(Ecore_Drm2_Output *output, int rotation)
136{
137 if (E_DRM2_EFL_VERSION_MINIMUM(1, 21, 99))
138 {
139 return sym_ecore_drm2_output_rotation_set_122(output, rotation);
140 }
141 return EINA_FALSE;
142}
143
115#undef E_DRM2_EFL_VERSION_MINIMUM 144#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)
295 Eina_Bool ok = EINA_FALSE; 295 Eina_Bool ok = EINA_FALSE;
296 Eina_Bool possible = EINA_FALSE; 296 Eina_Bool possible = EINA_FALSE;
297 297
298 if (!ecore_drm2_output_connected_get(output))
299 continue;
300
298 s = E_NEW(E_Randr2_Screen, 1); 301 s = E_NEW(E_Randr2_Screen, 1);
299 if (!s) continue; 302 if (!s) continue;
300 303
@@ -313,6 +316,7 @@ _drm2_randr_create(void)
313 s->id = malloc(strlen(s->info.name) + 1 + 1); 316 s->id = malloc(strlen(s->info.name) + 1 + 1);
314 if (!s->id) 317 if (!s->id)
315 { 318 {
319 free(s->info.name);
316 free(s->info.screen); 320 free(s->info.screen);
317 free(s->info.edid); 321 free(s->info.edid);
318 free(s); 322 free(s);
@@ -392,6 +396,8 @@ _drm2_randr_create(void)
392 396
393 if (ok) 397 if (ok)
394 { 398 {
399 int rotations;
400
395 if (!possible) 401 if (!possible)
396 { 402 {
397 unsigned int refresh; 403 unsigned int refresh;
@@ -413,13 +419,13 @@ _drm2_randr_create(void)
413 s->config.geom.w, s->config.geom.h); 419 s->config.geom.w, s->config.geom.h);
414 } 420 }
415 421
422 s->config.rotation = e_drm2_output_rotation_get(output);
423
416 s->info.can_rot_0 = EINA_FALSE; 424 s->info.can_rot_0 = EINA_FALSE;
417 s->info.can_rot_90 = EINA_FALSE; 425 s->info.can_rot_90 = EINA_FALSE;
418 s->info.can_rot_180 = EINA_FALSE; 426 s->info.can_rot_180 = EINA_FALSE;
419 s->info.can_rot_270 = EINA_FALSE; 427 s->info.can_rot_270 = EINA_FALSE;
420 428
421 int rotations;
422
423 rotations = 429 rotations =
424 ecore_drm2_output_supported_rotations_get(output); 430 ecore_drm2_output_supported_rotations_get(output);
425 431
@@ -520,106 +526,183 @@ _drm2_output_primary_set(const Eina_List *outputs, Ecore_Drm2_Output *output)
520 } 526 }
521} 527}
522 528
529static Eina_Bool
530_drm2_rotation_exists(Ecore_Drm2_Output *output, int rot)
531{
532 int rots;
533
534 rots = ecore_drm2_output_supported_rotations_get(output);
535 if (rots >= 0)
536 {
537 if ((rot == 0) && (rots & ECORE_DRM2_ROTATION_NORMAL))
538 return EINA_TRUE;
539 if ((rot == 90) && (rots & ECORE_DRM2_ROTATION_90))
540 return EINA_TRUE;
541 if ((rot == 180) && (rots & ECORE_DRM2_ROTATION_180))
542 return EINA_TRUE;
543 if ((rot == 270) && (rots & ECORE_DRM2_ROTATION_270))
544 return EINA_TRUE;
545 }
546
547 return EINA_FALSE;
548}
549
523static void 550static void
524_drm2_randr_apply(void) 551_drm2_randr_apply(void)
525{ 552{
526 const Eina_List *l;
527 Eina_List *ll;
528 E_Randr2_Screen *s;
529 Ecore_Drm2_Device *dev; 553 Ecore_Drm2_Device *dev;
530 const Eina_List *outputs; 554 Ecore_Drm2_Output **outconf, *out;
531 Ecore_Drm2_Output *output;
532 int minw, minh, maxw, maxh;
533 int ow = 0, oh = 0;
534 int pw = 0, ph = 0;
535 int vw = 0, vh = 0;
536 int nw = 0, nh = 0; 555 int nw = 0, nh = 0;
537 int top_priority = 0; 556 int minw, minh, maxw, maxh;
557 unsigned int *crtcs = NULL;
558 int num_crtcs = 0, numout = 0;
559 const Eina_List *outputs = NULL;
560 E_Randr2_Screen **screenconf;
538 561
562 /* get drm device */
539 dev = ecore_evas_data_get(e_comp->ee, "device"); 563 dev = ecore_evas_data_get(e_comp->ee, "device");
540 if (!dev) return; 564 if (!dev) return;
541 565
542 outputs = ecore_drm2_outputs_get(dev);
543 if (!outputs) return;
544
545 ecore_drm2_device_screen_size_range_get(dev, &minw, &minh, &maxw, &maxh);
546 printf("DRM2 RRR: size range: %ix%i -> %ix%i\n", minw, minh, maxw, maxh);
547
548 nw = e_randr2->w; 566 nw = e_randr2->w;
549 nh = e_randr2->h; 567 nh = e_randr2->h;
550 568
551 /* get virtual size */ 569 /* get screen size range */
552 EINA_LIST_FOREACH(outputs, l, output) 570 ecore_drm2_device_screen_size_range_get(dev, &minw, &minh, &maxw, &maxh);
553 { 571 printf("RRR: size range: %ix%i -> %ix%i\n", minw, minh, maxw, maxh);
554 if (!ecore_drm2_output_connected_get(output)) continue;
555 if (!ecore_drm2_output_enabled_get(output)) continue;
556 if (ecore_drm2_output_cloned_get(output)) continue;
557
558 e_drm2_output_info_get(output, NULL, NULL, &ow, &oh, NULL);
559 pw += MAX(pw, ow);
560 ph = MAX(ph, oh);
561 }
562
563 if (nw > maxw) nw = maxw;
564 if (nh > maxh) nh = maxh;
565 if (nw < minw) nw = minw;
566 if (nh < minh) nh = minh;
567 vw = nw;
568 vh = nh;
569 if (nw < pw) vw = pw;
570 if (nh < ph) vh = ph;
571 572
572 printf("DRM2 RRR: set vsize: %ix%i\n", vw, vh); 573 crtcs = ecore_drm2_device_crtcs_get(dev, &num_crtcs);
574 outputs = ecore_drm2_outputs_get(dev);
573 575
574 EINA_LIST_FOREACH(e_randr2->screens, ll, s) 576 if ((crtcs) && (outputs))
575 { 577 {
576 Ecore_Drm2_Output_Mode *mode = NULL; 578 E_Randr2_Screen *s;
577 579 Eina_List *l;
578 if (!s->config.configured) continue; 580 int top_priority = 0, i;
579
580 output = _drm2_output_find(outputs, s->info.name);
581 if (!output) continue;
582 581
583 if (s->config.enabled) 582 outconf = alloca(num_crtcs * sizeof(Ecore_Drm2_Output *));
584 mode = _drm2_mode_screen_find(s, output); 583 screenconf = alloca(num_crtcs * sizeof(E_Randr2_Screen *));
584 memset(outconf, 0, num_crtcs * sizeof(Ecore_Drm2_Output *));
585 memset(screenconf, 0, num_crtcs * sizeof(E_Randr2_Screen *));
585 586
586 if (s->config.priority > top_priority) 587 /* decide which outputs gets which crtcs */
587 top_priority = s->config.priority; 588 EINA_LIST_FOREACH(e_randr2->screens, l, s)
589 {
590 printf("RRR: find output for '%s'\n", s->info.name);
588 591
589 ecore_drm2_output_mode_set(output, mode, s->config.geom.x, 592 if (!s->config.configured)
590 s->config.geom.y); 593 {
594 printf("RRR: unconfigured screen: %s\n", s->info.name);
595 continue;
596 }
591 597
592 /* TODO: cannot support rotations until we support planes 598 out = _drm2_output_find(outputs, s->info.name);
593 * and we cannot support planes until Atomic support is in */ 599 if (out)
594 int orient = 0; 600 {
601 printf("RRR: enabled: %i\n", s->config.enabled);
602 if (s->config.enabled)
603 {
604 if (s->config.priority > top_priority)
605 top_priority = s->config.priority;
606
607 for (i = 0; i < num_crtcs; i++)
608 {
609 if (!outconf[i])
610 {
611 printf("RRR: crtc slot empty: %i\n", i);
612 if (ecore_drm2_output_possible_crtc_get(out, crtcs[i]))
613 {
614 if (_drm2_rotation_exists(out, s->config.rotation))
615 {
616 printf("RRR: assign slot out: %p\n", out);
617 outconf[i] = out;
618 screenconf[i] = s;
619 break;
620 }
621 }
622 }
623 }
624 }
625 }
626 }
595 627
596 if (s->config.rotation == 0) 628 numout = 0;
597 orient = ECORE_DRM2_ROTATION_NORMAL; 629 for (i = 0; i < num_crtcs; i++)
598 else if (s->config.rotation == 90) 630 if (outconf[i]) numout++;
599 orient = ECORE_DRM2_ROTATION_90;
600 else if (s->config.rotation == 180)
601 orient = ECORE_DRM2_ROTATION_180;
602 else if (s->config.rotation == 270)
603 orient = ECORE_DRM2_ROTATION_270;
604 631
605 ecore_drm2_output_rotation_set(output, orient); 632 if (numout)
633 {
634 for (i = 0; i < num_crtcs; i++)
635 {
636 if (outconf[i])
637 {
638 Ecore_Drm2_Output_Mode *mode;
639 Ecore_Drm2_Rotation orient = ECORE_DRM2_ROTATION_NORMAL;
640
641 mode = _drm2_mode_screen_find(screenconf[i], outconf[i]);
642 if (screenconf[i]->config.rotation == 0)
643 orient = ECORE_DRM2_ROTATION_NORMAL;
644 else if (screenconf[i]->config.rotation == 90)
645 orient = ECORE_DRM2_ROTATION_90;
646 else if (screenconf[i]->config.rotation == 180)
647 orient = ECORE_DRM2_ROTATION_180;
648 else if (screenconf[i]->config.rotation == 270)
649 orient = ECORE_DRM2_ROTATION_270;
650
651 printf("RRR: crtc on: %i = '%s' @ %i %i - %ix%i orient %i mode %p out %p\n",
652 i, screenconf[i]->info.name,
653 screenconf[i]->config.geom.x,
654 screenconf[i]->config.geom.y,
655 screenconf[i]->config.geom.w,
656 screenconf[i]->config.geom.h,
657 orient, mode, outconf[i]);
658
659 ecore_drm2_output_mode_set(outconf[i], mode,
660 screenconf[i]->config.geom.x,
661 screenconf[i]->config.geom.y);
662
663 ecore_drm2_output_relative_to_set(outconf[i],
664 screenconf[i]->config.relative.to);
665 ecore_drm2_output_relative_mode_set(outconf[i],
666 screenconf[i]->config.relative.mode);
667
668 if (screenconf[i]->config.priority == top_priority)
669 {
670 _drm2_output_primary_set(outputs, outconf[i]);
671 top_priority = -1;
672 }
673
674 ecore_drm2_output_enabled_set(outconf[i],
675 screenconf[i]->config.enabled);
676
677 e_drm2_output_rotation_set(outconf[i], orient);
678
679 ecore_evas_rotation_with_resize_set(e_comp->ee,
680 screenconf[i]->config.rotation);
681 }
682 else
683 {
684 printf("RRR: crtc off: %i\n", i);
685 /* FIXME: Need new drm2 API to disable crtc...
686 * one which Does Not Take an Output as param */
687 }
688 }
689 }
690 }
606 691
607 if (s->config.priority == top_priority) 692 /* free(outputs); */
608 _drm2_output_primary_set(outputs, output); 693 /* free(crtcs); */
609 694
610 ecore_drm2_output_enabled_set(output, s->config.enabled); 695 if (nw > maxw) nw = maxw;
696 if (nh > maxh) nh = maxh;
697 if (nw < minw) nw = minw;
698 if (nh < minh) nh = minh;
699 printf("RRR: set vsize: %ix%i\n", nw, nh);
700 ecore_drm2_device_calibrate(dev, nw, nh);
701 /* ecore_drm2_device_pointer_max_set(dev, nw, nh); */
702 ecore_drm2_device_pointer_rotation_set(dev, ecore_evas_rotation_get(e_comp->ee));
611 703
612 printf("\tDRM2 RRR: Mode\n"); 704 if (!e_randr2_cfg->ignore_hotplug_events)
613 printf("\t\tDRM2 RRR: Geom: %d %d %dx%d\n", 705 e_randr2_screen_refresh_queue(EINA_FALSE);
614 s->config.geom.x, s->config.geom.y,
615 s->config.mode.w, s->config.mode.h);
616 printf("\t\tDRM2 RRR: Refresh: %f\n", s->config.mode.refresh);
617 printf("\t\tDRM2 RRR: Preferred: %d\n", s->config.mode.preferred);
618 printf("\tDRM2 RRR: Rotation: %d\n", s->config.rotation);
619 printf("\tDRM2 RRR: Relative Mode: %d\n", s->config.relative.mode);
620 printf("\tDRM2 RRR: Relative To: %s\n", s->config.relative.to);
621 printf("\tDRM2 RRR: Align: %f\n", s->config.relative.align);
622 }
623} 706}
624 707
625static void 708static void