Driver.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /*
  2. * Copyright (c) 2022, Stephan Unverwerth <s.unverwerth@serenityos.org>
  3. * Copyright (c) 2023, Jelle Raaijmakers <jelle@gmta.nl>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <AK/HashMap.h>
  8. #include <AK/WeakPtr.h>
  9. #include <LibGPU/Driver.h>
  10. #include <dlfcn.h>
  11. namespace GPU {
  12. // FIXME: Think of a better way to configure these paths. Maybe use ConfigServer?
  13. // clang-format off
  14. static HashMap<StringView, char const*> const s_driver_path_map
  15. {
  16. #if defined(AK_OS_SERENITY)
  17. { "softgpu"sv, "libsoftgpu.so.serenity" },
  18. { "virtgpu"sv, "libvirtgpu.so.serenity" },
  19. #elif defined(AK_OS_MACOS)
  20. { "softgpu"sv, "liblagom-softgpu.dylib" },
  21. #else
  22. { "softgpu"sv, "liblagom-softgpu.so.0" },
  23. #endif
  24. };
  25. // clang-format on
  26. static HashMap<ByteString, WeakPtr<Driver>> s_loaded_drivers;
  27. ErrorOr<NonnullRefPtr<Driver>> Driver::try_create(StringView driver_name)
  28. {
  29. // Check if the library for this driver is already loaded
  30. auto already_loaded_driver = s_loaded_drivers.find(driver_name);
  31. if (already_loaded_driver != s_loaded_drivers.end() && !already_loaded_driver->value.is_null())
  32. return *already_loaded_driver->value;
  33. // Nope, we need to load the library
  34. auto it = s_driver_path_map.find(driver_name);
  35. if (it == s_driver_path_map.end())
  36. return Error::from_string_literal("The requested GPU driver was not found in the list of allowed driver libraries");
  37. auto lib = dlopen(it->value, RTLD_NOW);
  38. if (!lib)
  39. return Error::from_string_literal("The library for the requested GPU driver could not be opened");
  40. auto serenity_gpu_create_device = reinterpret_cast<serenity_gpu_create_device_t>(dlsym(lib, "serenity_gpu_create_device"));
  41. if (!serenity_gpu_create_device) {
  42. dlclose(lib);
  43. return Error::from_string_literal("The library for the requested GPU driver does not contain serenity_gpu_create_device()");
  44. }
  45. auto driver = adopt_ref(*new Driver(lib, serenity_gpu_create_device));
  46. s_loaded_drivers.set(driver_name, driver->make_weak_ptr());
  47. return driver;
  48. }
  49. Driver::~Driver()
  50. {
  51. dlclose(m_dlopen_result);
  52. }
  53. ErrorOr<NonnullOwnPtr<Device>> Driver::try_create_device(Gfx::IntSize size)
  54. {
  55. auto device_or_null = m_serenity_gpu_create_device(size);
  56. if (!device_or_null)
  57. return Error::from_string_literal("Could not create GPU device");
  58. return adopt_own(*device_or_null);
  59. }
  60. }