NativeWindowSdl.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <AnKi/Window/NativeWindowSdl.h>
  6. #include <AnKi/Util/Logger.h>
  7. #if ANKI_GR_BACKEND_VULKAN
  8. # include <SDL3/SDL_vulkan.h>
  9. #endif
  10. namespace anki {
  11. template<>
  12. template<>
  13. NativeWindow& MakeSingletonPtr<NativeWindow>::allocateSingleton<>()
  14. {
  15. ANKI_ASSERT(m_global == nullptr);
  16. m_global = new NativeWindowSdl();
  17. #if ANKI_ASSERTIONS_ENABLED
  18. ++g_singletonsAllocated;
  19. #endif
  20. return *m_global;
  21. }
  22. template<>
  23. void MakeSingletonPtr<NativeWindow>::freeSingleton()
  24. {
  25. if(m_global)
  26. {
  27. delete static_cast<NativeWindowSdl*>(m_global);
  28. m_global = nullptr;
  29. #if ANKI_ASSERTIONS_ENABLED
  30. --g_singletonsAllocated;
  31. #endif
  32. }
  33. }
  34. Error NativeWindow::init([[maybe_unused]] U32 targetFps, CString title)
  35. {
  36. return static_cast<NativeWindowSdl*>(this)->initSdl(title);
  37. }
  38. void NativeWindow::setWindowTitle(CString title)
  39. {
  40. NativeWindowSdl* self = static_cast<NativeWindowSdl*>(this);
  41. SDL_SetWindowTitle(self->m_sdlWindow, title.cstr());
  42. }
  43. NativeWindowSdl::~NativeWindowSdl()
  44. {
  45. if(m_sdlWindow)
  46. {
  47. SDL_DestroyWindow(m_sdlWindow);
  48. }
  49. SDL_QuitSubSystem(kInitSubsystems);
  50. SDL_Quit();
  51. }
  52. Error NativeWindowSdl::initSdl(CString title)
  53. {
  54. #if ANKI_OS_WINDOWS
  55. // Tell windows that the app will handle scaling. Otherwise SDL_GetDesktopDisplayMode will return a resolution that has the scaling applied
  56. if(!SetProcessDPIAware())
  57. {
  58. ANKI_WIND_LOGE("SetProcessDPIAware() failed");
  59. }
  60. #endif
  61. if(!SDL_Init(kInitSubsystems))
  62. {
  63. ANKI_WIND_LOGE("SDL_Init() failed: %s", SDL_GetError());
  64. return Error::kFunctionFailed;
  65. }
  66. #if ANKI_GR_BACKEND_VULKAN
  67. if(!SDL_Vulkan_LoadLibrary(nullptr))
  68. {
  69. ANKI_WIND_LOGE("SDL_Vulkan_LoadLibrary() failed: %s", SDL_GetError());
  70. return Error::kFunctionFailed;
  71. }
  72. #endif
  73. //
  74. // Set GL attributes
  75. //
  76. ANKI_WIND_LOGI("Creating SDL window. SDL version %u.%u. Display server %s", SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_GetCurrentVideoDriver());
  77. //
  78. // Create window
  79. //
  80. U32 flags = SDL_WINDOW_INPUT_FOCUS | SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_HIGH_PIXEL_DENSITY;
  81. #if ANKI_GR_BACKEND_VULKAN
  82. flags |= SDL_WINDOW_VULKAN;
  83. #endif
  84. if(g_cvarWindowBorderless)
  85. {
  86. flags |= SDL_WINDOW_BORDERLESS;
  87. }
  88. if(g_cvarWindowMaximized)
  89. {
  90. flags |= SDL_WINDOW_MAXIMIZED | SDL_WINDOW_RESIZABLE;
  91. }
  92. U32 width, height;
  93. if(g_cvarWindowFullscreen > 0)
  94. {
  95. if(g_cvarWindowFullscreen == 2)
  96. {
  97. flags |= SDL_WINDOW_FULLSCREEN;
  98. }
  99. SDL_DisplayID display = SDL_GetPrimaryDisplay();
  100. if(!display)
  101. {
  102. ANKI_WIND_LOGE("SDL_GetPrimaryDisplay() failed: %s", SDL_GetError());
  103. return Error::kFunctionFailed;
  104. }
  105. // Alter the window size
  106. const SDL_DisplayMode* mode = SDL_GetCurrentDisplayMode(display);
  107. if(!mode)
  108. {
  109. ANKI_WIND_LOGE("SDL_GetCurrentDisplayMode() failed: %s", SDL_GetError());
  110. return Error::kFunctionFailed;
  111. }
  112. width = U32(F32(mode->w) * mode->pixel_density);
  113. height = U32(F32(mode->h) * mode->pixel_density);
  114. }
  115. else
  116. {
  117. width = g_cvarWindowWidth;
  118. height = g_cvarWindowHeight;
  119. }
  120. m_sdlWindow = SDL_CreateWindow(title.cstr(), width, height, flags);
  121. if(m_sdlWindow == nullptr)
  122. {
  123. ANKI_WIND_LOGE("SDL_CreateWindow() failed");
  124. return Error::kFunctionFailed;
  125. }
  126. if(!SDL_ShowWindow(m_sdlWindow))
  127. {
  128. ANKI_WIND_LOGE("SDL_ShowWindow() failed: %s", SDL_GetError());
  129. }
  130. // Get the actual width and height
  131. {
  132. int w, h;
  133. SDL_GetWindowSize(m_sdlWindow, &w, &h);
  134. if(g_cvarWindowMaximized)
  135. {
  136. m_width = w;
  137. m_height = h;
  138. }
  139. else
  140. {
  141. m_width = width;
  142. m_height = height;
  143. ANKI_ASSERT(m_width == U32(w) && m_height == U32(h));
  144. }
  145. }
  146. ANKI_WIND_LOGI("SDL window created");
  147. return Error::kNone;
  148. }
  149. } // end namespace anki