33#include <simgear/compiler.h>
34#include <simgear/debug/logstream.hxx>
35#include <simgear/props/props_io.hxx>
36#include <simgear/structure/exception.hxx>
37#include <simgear/scene/util/OsgIoCapture.hxx>
40#include <osg/GraphicsContext>
46#include <osg/Viewport>
47#include <osgViewer/GraphicsWindow>
48#include <osgViewer/Viewer>
49#include <osgViewer/ViewerEventHandlers>
68#if defined(SG_WINDOWS)
81 osg::NotifySeverity severity = osg::getNotifyLevel();
82 string val = simgear::strutils::lowercase(node->getStringValue());
85 severity = osg::FATAL;
86 }
else if (val ==
"warn") {
88 }
else if (val ==
"notice") {
89 severity = osg::NOTICE;
90 }
else if (val ==
"info") {
92 }
else if ((val ==
"debug") || (val ==
"debug-info")) {
93 severity = osg::DEBUG_INFO;
96 osg::setNotifyLevel(severity);
106 osg::setNotifyHandler(
new SGNotifyHandler);
108 auto composite_viewer =
dynamic_cast<osgViewer::CompositeViewer*
>(
109 globals->get_renderer()->getViewerBase());
110 if (composite_viewer) {
111 osgViewer::ViewerBase* viewer =
globals->get_renderer()->getViewerBase();
112 osgViewer::View* view =
new osgViewer::View;
113 view->setFrameStamp(composite_viewer->getFrameStamp());
114 globals->get_renderer()->setView(view);
115 assert(
globals->get_renderer()->getView() == view);
119 view->getDatabasePager()->setUnrefImageDataAfterApplyPolicy(
true,
false);
125 view->getCamera()->setGraphicsContext(
nullptr);
128 mode =
fgGetString(
"/sim/rendering/multithreading-mode",
"SingleThreaded");
129 SG_LOG(SG_VIEW, SG_INFO,
"mode=" << mode);
130 if (mode ==
"AutomaticSelection")
131 viewer->setThreadingModel(osgViewer::Viewer::AutomaticSelection);
132 else if (mode ==
"CullDrawThreadPerContext")
133 viewer->setThreadingModel(osgViewer::Viewer::CullDrawThreadPerContext);
134 else if (mode ==
"DrawThreadPerContext")
135 viewer->setThreadingModel(osgViewer::Viewer::DrawThreadPerContext);
136 else if (mode ==
"CullThreadPerCameraDrawThreadPerContext")
137 viewer->setThreadingModel(osgViewer::Viewer::CullThreadPerCameraDrawThreadPerContext);
139 viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
146 if (wsa->
windows.size() != 1) {
149 view->getCamera()->setProjectionResizePolicy(osg::Camera::FIXED);
150 view->addEventHandler(manipulator);
152 viewer->setKeyEventSetsDone(0);
154 view->setSceneData(
new osg::Group);
163inline void setNumDatabaseThreads(
int threads) { DisplaySettings::instance()->setNumOfDatabaseThreadsHint(max(threads, 1)); DisplaySettings::instance()->setNumOfHttpDatabaseThreadsHint(0); }
167 SGPropertyNode* osgLevel =
fgGetNode(
"/sim/rendering/osg-notify-level",
true);
175 globals->addListenerToCleanup(l);
176 osgLevel->addChangeListener(l,
true);
180 Viewport* guiViewport = guiCamera->getViewport();
181 fgSetInt(
"/sim/startup/xsize", guiViewport->width());
182 fgSetInt(
"/sim/startup/ysize", guiViewport->height());
201 renderer->
getView()->getDatabasePager()->cancel();
207 osg::setNotifyHandler(
new osg::StandardNotifyHandler);
215 snprintf(
command,
sizeof(
command),
"for i in `ls /proc/%i/task/`; do taskset -p $i; done 1>&2", getpid());
216 SG_LOG(SG_VIEW, SG_ALERT,
"Running: " <<
command);
222static std::ostream&
operator<<(std::ostream& out,
const cpu_set_t& mask)
225 unsigned char* mask2 = (
unsigned char*)&mask;
226 for (
unsigned i = 0;
i <
sizeof(mask); ++
i) {
228 snprintf(buffer,
sizeof(buffer),
"%02x", (
unsigned)mask2[
i]);
247 m_node =
globals->get_props()->getNode(
"/sim/affinity-control",
true );
248 m_node->addChangeListener(
this);
253 std::string s =
m_node->getStringValue();
255 SG_LOG(SG_VIEW, SG_ALERT,
"Ignoring m_node=" << s <<
" because same as m_state.");
256 }
else if (s ==
"clear") {
258 snprintf(buffer,
sizeof(buffer),
"/proc/%i/task", getpid());
260 simgear::Dir dir(path);
261 m_thread_masks.clear();
262 simgear::PathList pids = dir.children(
263 simgear::Dir::TYPE_DIR | simgear::Dir::NO_DOT_OR_DOTDOT);
264 for (SGPath path : pids) {
265 std::string leaf = path.file();
266 int pid =
atoi(leaf.c_str());
268 int e = sched_getaffinity(pid,
sizeof(mask), &mask);
269 SG_LOG(SG_VIEW, SG_ALERT,
"Called sched_getaffinity()"
270 <<
" pid=" << pid <<
" => e=" << e <<
" mask=" << mask);
272 m_thread_masks[pid] = mask;
273 memset(&mask, 255,
sizeof(mask));
274 e = sched_setaffinity(pid,
sizeof(mask), &mask);
275 SG_LOG(SG_VIEW, SG_ALERT,
"Called sched_setaffinity()"
276 <<
" pid=" << pid <<
" => e=" << e <<
" mask=" << mask);
281 }
else if (s ==
"revert") {
282 for (
auto it : m_thread_masks) {
283 pid_t pid = it.first;
284 cpu_set_t mask = it.second;
285 int e = sched_setaffinity(pid,
sizeof(mask), &mask);
286 SG_LOG(SG_VIEW, SG_ALERT,
"Called sched_setaffinity()"
287 <<
" pid=" << pid <<
" => e=" << e <<
" mask=" << mask);
290 m_thread_masks.clear();
293 SG_LOG(SG_VIEW, SG_ALERT,
"Unrecognised m_node=" << s);
300 std::map<int, cpu_set_t> m_thread_masks;
308 osgViewer::ViewerBase* viewer_base =
globals->get_renderer()->getViewerBase();
309 viewer_base->setReleaseContextAtEndOfFrameHint(
false);
310 if (!viewer_base->isRealized()) {
311 viewer_base->realize();
312 std::string affinity =
fgGetString(
"/sim/thread-cpu-affinity");
313 if (affinity !=
"") {
315 if (affinity ==
"osg") {
316 SG_LOG(SG_VIEW, SG_INFO,
"Resetting affinity of current thread getpid()=" << getpid());
317 OpenThreads::Affinity affinity;
318 OpenThreads::SetProcessorAffinityOfCurrentThread(affinity);
324 while (!viewer_base->done()) {
329 if (
fgGetBool(
"/sim/position-finalized",
false)) {
338 double lastSimFrame_ms =
_lastUpdate.elapsedMSec();
339 double idle_wait = 0;
342 if (lastSimFrame_ms > 0) {
343 totalSimTime += lastSimFrame_ms - idle_wait;
347 simHost->setDoubleValue(totalSimTime / curFrameCount);
352 globals->get_renderer()->update();
354 VRManager::instance()->update();
356 viewer_base->frame(
globals->get_sim_time_sec());
381 fgSetDouble(
"/sim/rendering/gui-pixel-ratio", 1.0);
388 globals->get_renderer()->init();
399 osgViewer::ViewerBase* viewer_base =
globals->get_renderer()->getViewerBase();
406 viewer_base->stopThreading();
410 VRManager::instance()->destroyAndWait();
420 osgViewer::ViewerBase* viewer_base =
globals->get_renderer()->getViewerBase();
421 std::vector<osgViewer::GraphicsWindow*> windows;
422 viewer_base->getWindows(windows);
429 osgViewer::GraphicsWindow* window = windows[0];
431 osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();
433 SG_LOG(SG_VIEW, SG_ALERT,
"ERROR: No WindowSystemInterface available. Cannot toggle window fullscreen.");
437 static int previous_x = 0;
438 static int previous_y = 0;
439 static int previous_width = 800;
440 static int previous_height = 600;
442 unsigned int screenWidth;
443 unsigned int screenHeight;
444 wsi->getScreenResolution(*(window->getTraits()), screenWidth, screenHeight);
450 window->getWindowRectangle(x, y, width, height);
458 bool isFullScreen = !window->getWindowDecoration();
460 SG_LOG(SG_VIEW, SG_DEBUG,
"Toggling fullscreen. Previous window rectangle (" << x <<
", " << y <<
") x (" << width <<
", " << height <<
"), fullscreen: " << isFullScreen <<
", number of screens: " << wsi->getNumScreens());
463 if (previous_x + previous_width > (
int)screenWidth)
465 if (previous_y + previous_height > (
int)screenHeight)
471 width = previous_width;
472 height = previous_height;
477 previous_width = width;
478 previous_height = height;
484 height = screenHeight;
488 fgSetInt(
"/sim/startup/xsize", width);
489 fgSetInt(
"/sim/startup/ysize", height);
490 fgSetBool(
"/sim/startup/fullscreen", !isFullScreen);
493 window->setWindowDecoration(isFullScreen);
494 window->setWindowRectangle(x, y, width, height);
495 window->grabFocusIfPointerInWindow();
void cocoaRegisterTerminateHandler()
AppKit shuts us down via exit(), the code in main to cleanup is not run in that scenario.
virtual Cursor getCursor() const
virtual void setCursor(Cursor aCursor)=0
static FGMouseCursor * instance()
osgViewer::View * getView()
flightgear::FGEventHandler * getEventHandler()
osgViewer::ViewerBase * getViewerBase() const
static void resetPagerSingleton()
static flightgear::SceneryPager * getPagerSingleton()
void valueChanged(SGPropertyNode *node)
static CameraGroup * getDefault()
Get the default CameraGroup.
static void buildDefaultGroup(osgViewer::View *view)
Set the default CameraGroup, which is the only one that matters at this time.
static void setDefault(CameraGroup *group)
int getCurrentModifiers() const
void setResizable(bool _resizable)
static void initWindowBuilder()
Initialize the singleton window builder.
Adapter from windows system / graphics context management API to functions used by flightgear.
static void setWSA(WindowSystemAdapter *wsa)
Set the global adapter.
WindowVector windows
Vector of all the registered windows.
static WindowSystemAdapter * getWSA()
Get the global WindowSystemAdapter.
SGCommandMgr::command_t command
void updateOSGNotifyLevel()
void fgSetMouseCursor(FGMouseCursor::Cursor cursor)
SGPropertyNode * simTotalHostTime
int getNumDatabaseThreads()
void fgOSResetProperties()
static void ShowAffinities()
SGPropertyNode * frameWait
SGPropertyNode * simFrameCount
FGMouseCursor::Cursor fgGetMouseCursor()
SGPropertyNode * simFrameResetCount
void fgWarpMouse(int x, int y)
void setNumDatabaseThreads(int threads)
void fgOSInit(int *argc, char **argv)
std::string fgGetString(const char *name, const char *defaultValue)
Get a string value for a property.
bool fgSetInt(const char *name, int val)
Set an int value for a property.
void fgTie(const char *name, V(*getter)(), void(*setter)(V)=0, bool useDefault=true)
Tie a property to a pair of simple functions.
FlightPlan.hxx - defines a full flight-plan object, including departure, cruise, arrival information ...
void addSentryBreadcrumb(const std::string &, const std::string &)
osg::Camera * getGUICamera(CameraGroup *cgroup)
Get the osg::Camera that draws the GUI, if any, from a camera group.
void warpGUIPointer(CameraGroup *cgroup, int x, int y)
Warp the pointer to coordinates in the GUI camera of a camera group.
static int atoi(const string &str)
bool fgSetDouble(const char *name, double defaultValue)
Set a double value for a property.
bool fgGetBool(char const *name, bool def)
Get a bool value for a property.
bool fgSetBool(char const *name, bool val)
Set a bool value for a property.
SGPropertyNode * fgGetNode(const char *path, bool create)
Get a property node.
std::ostream & operator<<(std::ostream &out, const FGFrameInfo &frame_info)
void valueChanged(SGPropertyNode *node) override
SGPropertyNode_ptr m_node