app_server: Refactor and improve graphics device iteration.

* Do not open() devices while looping but only open() the one
   we were actually asked to open.

 * Try the VESA or Framebuffer driver even if deviceNumber is something
   other than 1.

 * Start iterating at 0 instead of 1 following loop iteration changes.

Ideally this iteration should occur a completely different way, in order
to properly support multiple graphics cards, but that's a problem for
another day.

Fixes #4303.
This commit is contained in:
Augustin Cavalier
2022-07-06 19:52:23 -04:00
parent ab8109c152
commit 5c3aa92735
@@ -197,7 +197,7 @@ AccelerantHWInterface::Initialize()
return B_NO_MEMORY; return B_NO_MEMORY;
if (ret >= B_OK) { if (ret >= B_OK) {
for (int32 i = 1; fCardFD != B_ENTRY_NOT_FOUND; i++) { for (int32 i = 0; fCardFD != B_ENTRY_NOT_FOUND; i++) {
fCardFD = _OpenGraphicsDevice(i); fCardFD = _OpenGraphicsDevice(i);
if (fCardFD < 0) { if (fCardFD < 0) {
ATRACE(("Failed to open graphics device\n")); ATRACE(("Failed to open graphics device\n"));
@@ -234,52 +234,45 @@ AccelerantHWInterface::Initialize()
int int
AccelerantHWInterface::_OpenGraphicsDevice(int deviceNumber) AccelerantHWInterface::_OpenGraphicsDevice(int deviceNumber)
{ {
DIR *directory = opendir("/dev/graphics");
if (!directory)
return -1;
int device = -1; int device = -1;
int count = 0; int count = 0;
if (!use_fail_safe_video_mode()) { if (!use_fail_safe_video_mode()) {
// TODO: We do not need to avoid the "vesa" or "framebuffer" drivers this way DIR *directory = opendir("/dev/graphics");
// once they been ported to the new driver architecture - the special case here if (!directory)
// can then be removed. return -1;
struct dirent *entry; struct dirent *entry;
char path[PATH_MAX]; char path[PATH_MAX];
while (count < deviceNumber && (entry = readdir(directory)) != NULL) { while ((entry = readdir(directory)) != NULL) {
if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..") if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")
|| !strcmp(entry->d_name, "vesa") || !strcmp(entry->d_name, "framebuffer")) || !strcmp(entry->d_name, "vesa") || !strcmp(entry->d_name, "framebuffer"))
continue; continue;
if (device >= 0) { if (count == deviceNumber) {
close(device); sprintf(path, "/dev/graphics/%s", entry->d_name);
device = -1; device = open(path, B_READ_WRITE);
break;
} }
sprintf(path, "/dev/graphics/%s", entry->d_name); count++;
device = open(path, B_READ_WRITE);
if (device >= 0)
count++;
} }
closedir(directory);
} }
// Open VESA or Framebuffer driver if we were not able to get a better one. // Open VESA or Framebuffer driver if we were not able to get a better one.
if (count < deviceNumber) { if (count < deviceNumber) {
if (deviceNumber == 1) { device = open("/dev/graphics/vesa", B_READ_WRITE);
device = open("/dev/graphics/vesa", B_READ_WRITE); if (device > 0) {
if (device > 0) { // store the device, so that we can access the planar blitter
// store the device, so that we can access the planar blitter fVGADevice = device;
fVGADevice = device;
} else {
device = open("/dev/graphics/framebuffer", B_READ_WRITE);
}
} else { } else {
close(device); device = open("/dev/graphics/framebuffer", B_READ_WRITE);
device = B_ENTRY_NOT_FOUND;
} }
}
closedir(directory); if (device < 0)
return B_ENTRY_NOT_FOUND;
}
return device; return device;
} }