summaryrefslogtreecommitdiff
path: root/src/lib/ecore_x
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2018-10-09 12:57:00 +0100
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2018-10-11 16:25:05 +0100
commitd67e9875c83966504b052c30ddee018e35b2dff4 (patch)
treeb3d06c62143c668ce151dd7071f07000fb90e505 /src/lib/ecore_x
parenta82b24aaa8dfbfe2c15dfa69beba0f1fe68b5a1b (diff)
ecore_x - add nouveau into the whitelist and clean up so it's a list
it was a lot of if cases before now it's an array with min version parameters and globs for matching drivers etc. - much cleaner and neater to afdd things to the whtielist now.
Diffstat (limited to 'src/lib/ecore_x')
-rw-r--r--src/lib/ecore_x/ecore_x_vsync.c234
1 files changed, 98 insertions, 136 deletions
diff --git a/src/lib/ecore_x/ecore_x_vsync.c b/src/lib/ecore_x/ecore_x_vsync.c
index 08a6796..05e18ed 100644
--- a/src/lib/ecore_x/ecore_x_vsync.c
+++ b/src/lib/ecore_x/ecore_x_vsync.c
@@ -15,6 +15,7 @@
15#include <sys/stat.h> 15#include <sys/stat.h>
16#include <sys/select.h> 16#include <sys/select.h>
17#include <fcntl.h> 17#include <fcntl.h>
18#include <fnmatch.h>
18 19
19#ifdef HAVE_PRCTL 20#ifdef HAVE_PRCTL
20# include <sys/prctl.h> 21# include <sys/prctl.h>
@@ -451,65 +452,89 @@ _drm_link(void)
451 452
452#define DRM_HAVE_NVIDIA 1 453#define DRM_HAVE_NVIDIA 1
453 454
455static Eina_Bool
456glob_match(const char *glob, const char *str)
457{
458 if (!glob) return EINA_TRUE;
459 if (!str) return EINA_FALSE;
460 if (!fnmatch(glob, str, 0)) return EINA_TRUE;
461 return EINA_FALSE;
462}
463
454static int 464static int
455_drm_init(int *flags) 465_drm_init(int *flags)
456{ 466{
467 // whitelist of known-to-work drivers
468 struct whitelist_card
469 {
470 const char *name_glob;
471 const char *desc_glob;
472 const char *date_glob;
473 int drm_ver_min_maj;
474 int drm_ver_min_min;
475 int kernel_ver_min_maj;
476 int kernel_ver_min_min;
477 };
478 static const struct whitelist_card whitelist[] = {
479 { "exynos", "*Samsung*", NULL, 1, 6, 3, 0 },
480 { "i915", "*Intel*", NULL, 1, 6, 3, 14 },
481 { "radeon", "*Radeon*", NULL, 2, 39, 3, 14 },
482 { "amdgpu", "*AMD*", NULL, 3, 0, 4, 9 },
483 { "nouveau", "*nVidia*", "201[23456789]*", 1, 3, 4, 9 },
484 { "nouveau", "*nVidia*", "202[0123456789]*", 1, 3, 4, 9 },
485 { NULL, NULL, NULL, 0, 0, 0, 0 }
486 };
487 int i;
457 struct stat st; 488 struct stat st;
458 char buf[512]; 489 char buf[512];
459 Eina_Bool ok = EINA_FALSE; 490 Eina_Bool ok = EINA_FALSE;
460 int vmaj = 0, vmin = 0; 491 int vmaj = 0, vmin = 0;
492 FILE *fp;
461 493
462 // vboxvideo 4.3.14 is crashing when calls drmWaitVBlank() 494 // vboxvideo 4.3.14 is crashing when calls drmWaitVBlank()
463 // https://www.virtualbox.org/ticket/13265 495 // https://www.virtualbox.org/ticket/13265
464 // also affects 4.3.12 496 // also affects 4.3.12
465 if (stat("/sys/module/vboxvideo", &st) == 0) 497 if (stat("/sys/module/vboxvideo", &st) == 0) return 0;
466 { 498
467/*
468 FILE *fp = fopen("/sys/module/vboxvideo/version", "rb");
469 if (fp)
470 {
471 if (fgets(buf, sizeof(buf), fp))
472 {
473 if (eina_str_has_prefix(buf, "4.3.14"))
474 {
475 fclose(fp);
476 return 0;
477 }
478 }
479 fclose(fp);
480 }
481 */
482 return 0;
483 }
484 // only do this on new kernels = let's say 3.14 and up. 3.16 definitely 499 // only do this on new kernels = let's say 3.14 and up. 3.16 definitely
485 // works 500 // works
501 fp = fopen("/proc/sys/kernel/osrelease", "rb");
502 if (fp)
486 { 503 {
487 FILE *fp = fopen("/proc/sys/kernel/osrelease", "rb"); 504 if (fgets(buf, sizeof(buf), fp))
488 if (fp)
489 { 505 {
490 if (fgets(buf, sizeof(buf), fp)) 506 if (sscanf(buf, "%i.%i.%*s", &vmaj, &vmin) == 2)
491 { 507 {
492 if (sscanf(buf, "%i.%i.%*s", &vmaj, &vmin) == 2) 508 if (vmaj >= 3) ok = EINA_TRUE;
493 {
494 if (vmaj >= 3) ok = EINA_TRUE;
495 }
496 } 509 }
497 fclose(fp);
498 } 510 }
499 if (!ok) return 0; 511 fclose(fp);
500 } 512 }
513 if (!ok) return 0;
501 ok = EINA_FALSE; 514 ok = EINA_FALSE;
502 515
503 snprintf(buf, sizeof(buf), "/dev/dri/card1"); 516 snprintf(buf, sizeof(buf), "/dev/dri/card1");
504 if (stat(buf, &st) == 0) 517 if (stat(buf, &st) == 0)
505 { 518 {
506 // XXX: 2 dri cards - ambiguous. unknown device for screen 519 // XXX: 2 dri cards - ambiguous. unknown device for screen
520 if (getenv("ECORE_VSYNC_DRM_VERSION_DEBUG"))
521 fprintf(stderr, "You have 2 DRI cards. Don't know which to use for vsync\n");
507 return 0; 522 return 0;
508 } 523 }
509 snprintf(buf, sizeof(buf), "/dev/dri/card0"); 524 snprintf(buf, sizeof(buf), "/dev/dri/card0");
510 if (stat(buf, &st) != 0) return 0; 525 if (stat(buf, &st) != 0)
526 {
527 if (getenv("ECORE_VSYNC_DRM_VERSION_DEBUG"))
528 fprintf(stderr, "Cannot find device card 0 (/de/dri/card0)\n");
529 return 0;
530 }
511 drm_fd = open(buf, O_RDWR | O_CLOEXEC); 531 drm_fd = open(buf, O_RDWR | O_CLOEXEC);
512 if (drm_fd < 0) return 0; 532 if (drm_fd < 0)
533 {
534 if (getenv("ECORE_VSYNC_DRM_VERSION_DEBUG"))
535 fprintf(stderr, "Cannot open device card 0 (/de/dri/card0)\n");
536 return 0;
537 }
513 538
514 if (!getenv("ECORE_VSYNC_DRM_ALL")) 539 if (!getenv("ECORE_VSYNC_DRM_ALL"))
515 { 540 {
@@ -520,6 +545,8 @@ _drm_init(int *flags)
520 drmverbroken = (drmVersionBroken *)drmver; 545 drmverbroken = (drmVersionBroken *)drmver;
521 if (!drmver) 546 if (!drmver)
522 { 547 {
548 if (getenv("ECORE_VSYNC_DRM_VERSION_DEBUG"))
549 fprintf(stderr, "Cannot get dri version info from drmGetVersion()\n");
523 close(drm_fd); 550 close(drm_fd);
524 return 0; 551 return 0;
525 } 552 }
@@ -549,148 +576,81 @@ _drm_init(int *flags)
549 drmver->version_major, drmver->version_minor, 576 drmver->version_major, drmver->version_minor,
550 drmver->name, drmver->date, drmver->desc); 577 drmver->name, drmver->date, drmver->desc);
551 } 578 }
579
552 if ((((drmver->version_major == 1) && 580 if ((((drmver->version_major == 1) &&
553 (drmver->version_minor >= 6)) || 581 (drmver->version_minor >= 3)) ||
554 (drmver->version_major > 1)) && 582 (drmver->version_major > 1)) &&
555 (drmver->name > (char *)4000L) && 583 (drmver->name > (char *)4000L) &&
556 (drmver->date_len < 200)) 584 (drmver->date_len < 200))
557 { 585 {
558 // whitelist of known-to-work drivers 586 if ((!strcmp(drmver->name, "nvidia-drm")) &&
559 if ((!strcmp(drmver->name, "exynos")) && 587 (strstr(drmver->desc, "NVIDIA DRM driver")))
560 (strstr(drmver->desc, "Samsung")))
561 {
562 if (((vmaj >= 3) && (vmin >= 0)) || (vmaj >= 4))
563 {
564 if (getenv("ECORE_VSYNC_DRM_VERSION_DEBUG"))
565 fprintf(stderr, "Whitelisted exynos OK\n");
566 ok = EINA_TRUE;
567 goto checkdone;
568 }
569 }
570 if ((!strcmp(drmver->name, "i915")) &&
571 (strstr(drmver->desc, "Intel Graphics")))
572 {
573 if (((vmaj >= 3) && (vmin >= 14)) || (vmaj >= 4))
574 {
575 if (getenv("ECORE_VSYNC_DRM_VERSION_DEBUG"))
576 fprintf(stderr, "Whitelisted intel OK\n");
577 ok = EINA_TRUE;
578 goto checkdone;
579 }
580 }
581 if ((!strcmp(drmver->name, "radeon")) &&
582 (strstr(drmver->desc, "Radeon")) &&
583 (((drmver->version_major == 2) &&
584 (drmver->version_minor >= 39)) ||
585 (drmver->version_major > 2)))
586 { 588 {
587 if (((vmaj >= 3) && (vmin >= 14)) || (vmaj >= 4)) 589 if (((vmaj >= 3) && (vmin >= 14)) || (vmaj >= 4))
588 { 590 {
589 if (getenv("ECORE_VSYNC_DRM_VERSION_DEBUG")) 591 if (getenv("ECORE_VSYNC_DRM_VERSION_DEBUG"))
590 fprintf(stderr, "Whitelisted radeon OK\n"); 592 fprintf(stderr, "You have nVidia binary drivers - no vsync\n");
591 ok = EINA_TRUE; 593 *flags |= DRM_HAVE_NVIDIA;
592 goto checkdone; 594 goto checkdone;
593 } 595 }
594 } 596 }
595 if ((!strcmp(drmver->name, "amdgpu")) && 597 for (i = 0; whitelist[i].name_glob; i++)
596 (strstr(drmver->desc, "AMD")) &&
597 ((drmver->version_major > 2)))
598 { 598 {
599 if (((vmaj >= 3) && (vmin >= 14)) || (vmaj >= 4)) 599 if ((glob_match(whitelist[i].name_glob, drmver->name)) &&
600 (glob_match(whitelist[i].desc_glob, drmver->desc)) &&
601 (glob_match(whitelist[i].date_glob, drmver->date)) &&
602 ((drmver->version_major > whitelist[i].drm_ver_min_maj) ||
603 ((drmver->version_major == whitelist[i].drm_ver_min_maj) &&
604 (drmver->version_minor >= whitelist[i].drm_ver_min_min))) &&
605 ((vmaj > whitelist[i].kernel_ver_min_maj) ||
606 ((vmaj == whitelist[i].kernel_ver_min_maj) &&
607 (vmin >= whitelist[i].kernel_ver_min_min))))
600 { 608 {
601 if (getenv("ECORE_VSYNC_DRM_VERSION_DEBUG")) 609 if (getenv("ECORE_VSYNC_DRM_VERSION_DEBUG"))
602 fprintf(stderr, "Whitelisted amdgpu OK\n"); 610 fprintf(stderr, "Whitelisted %s OK\n",
611 whitelist[i].name_glob);
603 ok = EINA_TRUE; 612 ok = EINA_TRUE;
604 goto checkdone; 613 goto checkdone;
605 } 614 }
606 } 615 }
607 } 616 }
608 if ((((drmverbroken->version_major == 1) && 617 else if ((((drmverbroken->version_major == 1) &&
609 (drmverbroken->version_minor >= 6)) || 618 (drmverbroken->version_minor >= 3)) ||
610 (drmverbroken->version_major > 1)) && 619 (drmverbroken->version_major > 1)) &&
611 (drmverbroken->name > (char *)4000L) && 620 (drmverbroken->name > (char *)4000L) &&
612 (drmverbroken->date_len < 200)) 621 (drmverbroken->date_len < 200))
613 { 622 {
614 // whitelist of known-to-work drivers 623 if ((!strcmp(drmverbroken->name, "nvidia-drm")) &&
615 if ((!strcmp(drmverbroken->name, "exynos")) && 624 (strstr(drmverbroken->desc, "NVIDIA DRM driver")))
616 (strstr(drmverbroken->desc, "Samsung")))
617 {
618 if (((vmaj >= 3) && (vmin >= 0)) || (vmaj >= 4))
619 {
620 if (getenv("ECORE_VSYNC_DRM_VERSION_DEBUG"))
621 fprintf(stderr, "Whitelisted exynos OK\n");
622 ok = EINA_TRUE;
623 goto checkdone;
624 }
625 }
626 if ((!strcmp(drmverbroken->name, "i915")) &&
627 (strstr(drmverbroken->desc, "Intel Graphics")))
628 {
629 if (((vmaj >= 3) && (vmin >= 14)) || (vmaj >= 4))
630 {
631 if (getenv("ECORE_VSYNC_DRM_VERSION_DEBUG"))
632 fprintf(stderr, "Whitelisted intel OK\n");
633 ok = EINA_TRUE;
634 goto checkdone;
635 }
636 }
637 if ((!strcmp(drmverbroken->name, "radeon")) &&
638 (strstr(drmverbroken->desc, "Radeon")) &&
639 (((drmver->version_major == 2) &&
640 (drmver->version_minor >= 39)) ||
641 (drmver->version_major > 2)))
642 { 625 {
643 if (((vmaj >= 3) && (vmin >= 14)) || (vmaj >= 4)) 626 if (((vmaj >= 3) && (vmin >= 14)) || (vmaj >= 4))
644 { 627 {
645 if (getenv("ECORE_VSYNC_DRM_VERSION_DEBUG")) 628 if (getenv("ECORE_VSYNC_DRM_VERSION_DEBUG"))
646 fprintf(stderr, "Whitelisted radeon OK\n"); 629 fprintf(stderr, "You have nVidia binary drivers - no vsync\n");
647 ok = EINA_TRUE; 630 *flags |= DRM_HAVE_NVIDIA;
648 goto checkdone; 631 goto checkdone;
649 } 632 }
650 } 633 }
651 if ((!strcmp(drmverbroken->name, "amdgpu")) && 634 for (i = 0; whitelist[i].name_glob; i++)
652 (strstr(drmverbroken->desc, "AMD")) &&
653 ((drmverbroken->version_major > 2)))
654 { 635 {
655 if (((vmaj >= 3) && (vmin >= 14)) || (vmaj >= 4)) 636 if ((glob_match(whitelist[i].name_glob, drmverbroken->name)) &&
637 (glob_match(whitelist[i].desc_glob, drmverbroken->desc)) &&
638 (glob_match(whitelist[i].date_glob, drmverbroken->date)) &&
639 ((drmverbroken->version_major > whitelist[i].drm_ver_min_maj) ||
640 ((drmverbroken->version_major == whitelist[i].drm_ver_min_maj) &&
641 (drmverbroken->version_minor >= whitelist[i].drm_ver_min_min))) &&
642 ((vmaj > whitelist[i].kernel_ver_min_maj) ||
643 ((vmaj == whitelist[i].kernel_ver_min_maj) &&
644 (vmin >= whitelist[i].kernel_ver_min_min))))
656 { 645 {
657 if (getenv("ECORE_VSYNC_DRM_VERSION_DEBUG")) 646 if (getenv("ECORE_VSYNC_DRM_VERSION_DEBUG"))
658 fprintf(stderr, "Whitelisted amdgpu OK\n"); 647 fprintf(stderr, "Whitelisted %s OK\n",
648 whitelist[i].name_glob);
659 ok = EINA_TRUE; 649 ok = EINA_TRUE;
660 goto checkdone; 650 goto checkdone;
661 } 651 }
662 } 652 }
663 } 653 }
664 if ((drmver->version_major >= 0) &&
665 (drmver->version_minor >= 0) &&
666 (drmver->name > (char *)4000L) &&
667 (drmver->date_len < 200))
668 {
669 if ((!strcmp(drmver->name, "nvidia-drm")) &&
670 (strstr(drmver->desc, "NVIDIA DRM driver")))
671 {
672 if (((vmaj >= 3) && (vmin >= 14)) || (vmaj >= 4))
673 {
674 *flags |= DRM_HAVE_NVIDIA;
675 goto checkdone;
676 }
677 }
678 }
679 if ((drmverbroken->version_major >= 0) &&
680 (drmverbroken->version_minor >= 0) &&
681 (drmverbroken->name > (char *)4000L) &&
682 (drmverbroken->date_len < 200))
683 {
684 if ((!strcmp(drmverbroken->name, "nvidia-drm")) &&
685 (strstr(drmverbroken->desc, "NVIDIA DRM driver")))
686 {
687 if (((vmaj >= 3) && (vmin >= 14)) || (vmaj >= 4))
688 {
689 *flags |= DRM_HAVE_NVIDIA;
690 goto checkdone;
691 }
692 }
693 }
694checkdone: 654checkdone:
695 sym_drmFreeVersion(drmver); 655 sym_drmFreeVersion(drmver);
696 if (!ok) 656 if (!ok)
@@ -707,6 +667,8 @@ checkdone:
707 667
708 if (!_drm_tick_schedule()) 668 if (!_drm_tick_schedule())
709 { 669 {
670 if (getenv("ECORE_VSYNC_DRM_VERSION_DEBUG"))
671 fprintf(stderr, "Cannot schedule vblank tick.event...\n");
710 close(drm_fd); 672 close(drm_fd);
711 drm_fd = -1; 673 drm_fd = -1;
712 return 0; 674 return 0;