GLVis  v4.2
Accurate and flexible finite element visualization
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
sdl_main.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
2 // at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3 // LICENSE and NOTICE for details. LLNL-CODE-443271.
4 //
5 // This file is part of the GLVis visualization tool and library. For more
6 // information and source code availability see https://glvis.org.
7 //
8 // GLVis is free software; you can redistribute it and/or modify it under the
9 // terms of the BSD-3 license. We welcome feedback and contributions, see file
10 // CONTRIBUTING.md for details.
11 
12 #ifndef GLVIS_SDL_MAIN_HPP
13 #define GLVIS_SDL_MAIN_HPP
14 
15 #include <set>
16 #include <condition_variable>
17 
18 #include "sdl.hpp"
19 
21 {
22 private:
23  using Handle = SdlWindow::Handle;
24 public:
25  SdlMainThread();
27 
28  // If called, all SDL window operations are run immediately; this is for
29  // running in a single-threaded mode.
30  void SetSingleThread() { sdl_multithread = false; }
31 
32  bool SdlInitialized() const { return sdl_init; }
33 
34  // Handles all SDL operations that are expected to be handled on the main
35  // SDL thread (i.e. events and window creation)
36  void MainLoop(bool server_mode);
37 
38  // Dequeues all incoming events from SDL, and queues them up to their
39  // matching windows. Intended to be called only in single-threaded mode.
40  void DispatchSDLEvents();
41 
42  // Executed from a window worker thread. Returns a handle to a new window
43  // and associated OpenGL context.
44  Handle GetHandle(SdlWindow* wnd, const std::string& title,
45  int x, int y, int w, int h, bool legacyGlOnly);
46 
47  // Executed from a window worker thread. Deletes a handle to a window and
48  // the corresponding OpenGL context.
49  void DeleteHandle(Handle to_delete);
50 
51  // Issues a command on the main thread to set the window title.
52  void SetWindowTitle(const Handle& handle, std::string title);
53 
54  // Issues a command on the main thread to set the window size.
55  void SetWindowSize(const Handle& handle, int w, int h);
56 
57  // Issues a command on the main thread to set the window position.
58  void SetWindowPosition(const Handle& handle, int x, int y);
59 
60  SdlNativePlatform* GetPlatform() const { return platform.get(); }
61 
62 private:
63  struct CreateWindowCmd;
64  struct SdlCtrlCommand;
65 
66  enum class SdlCmdType
67  {
68  None,
69  Create,
70  Delete,
71  SetTitle,
72  SetSize,
74  };
75 
76  // Wakes up the main thread, if sleeping.
77  void SendEvent()
78  {
79  std::unique_lock<std::mutex> platform_lk{event_mtx};
80  event_cv.wait(platform_lk, [this]() { return try_create_platform; });
81  if (platform)
82  {
83  platform->SendEvent();
84  }
85  }
86 
87  void queueWindowEvent(SdlCtrlCommand cmd, bool sync = false);
88 
89  template<typename T>
90  Uint32 getWindowID(const T& eventStruct)
91  {
92  return eventStruct.windowID;
93  }
94 
95  void setWindowIcon(SDL_Window* hwnd);
96 
97  void handleWindowCmdImpl(SdlCtrlCommand& cmd);
98 
99  // Setup the correct OpenGL context flags in SDL for when we actually open the
100  // window.
101  void probeGLContextSupport(bool legacyGlOnly);
102 
103  void getDpi(const Handle& handle, int& wdpi, int& hdpi);
104 
105  void createWindowImpl(CreateWindowCmd& cmd);
106 
107  void handleBackgroundWindowEvent(SDL_WindowEvent e);
108 
109  bool sdl_init {false};
110  bool sdl_multithread {true};
111 
112  bool server_mode {false};
113 
114  // A flag indicating whether the main loop will *begin* terminating
115  bool terminating {false};
116  unique_ptr<SDL_Window, decltype(&SDL_DestroyWindow)> bg_wnd{nullptr, SDL_DestroyWindow};
117 
118  // -------------------------------------------------------------------------
119  // Objects for handling passing of window control commands to the main event
120  // loop.
121 
122  mutex window_cmd_mtx;
123  vector<SdlCtrlCommand> window_cmds;
124 
125  int num_windows {-1}; // -1: waiting for window to be created
126 
127  // -------------------------------------------------------------------------
128  // Objects for handling dispatching events from the main event loop to
129  // worker threads.
130 
131  unordered_map<int, SdlWindow*> hwnd_to_window;
132  unordered_map<int, vector<SDL_Event>> wnd_events;
133  std::set<SDL_FingerID> fingers;
134  bool disable_mouse {false};
135 
136  mutex gl_ctx_mtx;
137 
138  mutex event_mtx;
139  condition_variable event_cv;
140  bool try_create_platform{false};
141  unique_ptr<SdlNativePlatform> platform;
142 
143  int title_height_offset {0};
144 };
145 
146 #endif
thread_local SdlWindow * wnd
Definition: aux_vis.cpp:50
void SetWindowTitle(const Handle &handle, std::string title)
Definition: sdl_main.cpp:334
SdlNativePlatform * GetPlatform() const
Definition: sdl_main.hpp:60
Handle GetHandle(SdlWindow *wnd, const std::string &title, int x, int y, int w, int h, bool legacyGlOnly)
Definition: sdl_main.cpp:270
void MainLoop(bool server_mode)
Definition: sdl_main.cpp:98
void SetWindowPosition(const Handle &handle, int x, int y)
Definition: sdl_main.cpp:360
void SetSingleThread()
Definition: sdl_main.hpp:30
bool SdlInitialized() const
Definition: sdl_main.hpp:32
void DeleteHandle(Handle to_delete)
Definition: sdl_main.cpp:316
void DispatchSDLEvents()
Definition: sdl_main.cpp:188
void SetWindowSize(const Handle &handle, int w, int h)
Definition: sdl_main.cpp:347