Why does it take so long to open the window


#1

this is first it starts with the black window and then it renders the objects. this is estimated time to open the window takes about 1 minute to two minutes. My doubt is this to delay this whole time. sampled in the images.

Another question is to modify the input events if I gave an example.


#2

You are likely running in debug mode and/or importing assets during startup.


#3

Hey there,
I’m having the same issue and yes I’m currently working in debug build. I’m completely new to bsf and I compiled the framework from source (MSVC 2017).
My aim is to build a little game on top of bsf, therefore I’ll have to run the executable in debug mode frequently which unfortunately always takes up to a minute to be ready for anything else. That’s the code directly called from main.

void GameLoop::run()
{
	bs::START_UP_DESC startUpDesc;
	// Required plugins
	startUpDesc.renderAPI = "bsfD3D11RenderAPI";
	startUpDesc.renderer = "bsfRenderBeast";
	startUpDesc.audio = "bsfOpenAudio";
	startUpDesc.physics = "bsfPhysX";
	startUpDesc.input = "bsfOISInput";

	// List of importer plugins we plan on using for importing various resources
	startUpDesc.importers.clear();
	//startUpDesc.importers.push_back("bsfFreeImgImporter"); // For importing textures
	//startUpDesc.importers.push_back("bsfFBXImporter"); // For importing meshes
	//startUpDesc.importers.push_back("bsfFontImporter"); // For importing fonts
	//startUpDesc.importers.push_back("bsfSL"); // For importing shaders

	auto& windowsDesc = startUpDesc.primaryWindowDesc;
	windowsDesc.videoMode = bs::VideoMode(1280, 720);
	windowsDesc.title = "Example";
	windowsDesc.fullscreen = false;
	bs::Application::startUp(startUpDesc);

	auto sceneCameraSO = bs::SceneObject::create("SceneCamera");
	auto sceneCamera = sceneCameraSO->addComponent<bs::CCamera>();
	sceneCamera->setMain(true);
	sceneCameraSO->setPosition({ 40.0f, 30.0f, 230.0f });
	sceneCameraSO->lookAt({ 0, 0, 0 });

	bs::Application::instance().runMainLoop();
	bs::Application::shutDown();
}

It seems to be stuck in the BsModule.h at Line 92

/**
		 * Constructs and starts a specialized type of the module. Provided type must derive from type the Module is
		 * initialized with.
		 */
		template<class SubType, class ...Args>
		static void bs::Module<T>::startUp(Args &&...args)
		{
			static_assert(std::is_base_of<T, SubType>::value, "Provided type is not derived from type the Module is initialized with.");

			if (isStartedUp())
				BS_EXCEPT(InternalErrorException, "Trying to start an already started module.");

			_instance() = bs_new<SubType>(std::forward<Args>(args)...);
			isStartedUp() = true;

			((Module*)_instance())->onStartUp(); // this is the evil line
		}

Is there any other possibility to speed it up instead of compiling my game in release mode?

Greetings.


#4

The only reason the framework should ever take that long to start up is when it’s importing builtin assets, and that should only happen once. But I notice you are disabling importers, so it doesn’t seem likely that’s the cause. On the other hand it might also be causing the built-in import process to fail and then keep repeating every time you run the application. One of the things you can try is to enable all importers, run it and let it do its things. Then see if you also have the long wait next time.

Module is a generic class used for most systems in the framework, so that could be a lot of things. If you can find out the value of the template parameter T that would be helpful.

Also make sure to clear all your breakpoints. Setting a breakpoint in a busy part of code can slow down the program significantly.

What will definitely give you a performance boost is to run without a debugger attached (Debug->Start Without Debugging in Visual Studio). But application should start up in a matter of seconds even with the debugger attached and I’d love to find the real cause of the issue.


#5

Well, thanks for your reply.
I disabled the importers on purpose because I tried to eliminate those long loading times. I enabled them again, but nothing really changed.
To be more precise what’s happening:
When I start the program (via MSVC debugging) it shows a black main window; but it’s not responsible.
I have to wait ~35 seconds to get correct blue filled window.

I started the msvc cpu profiling tool and got this hot path:
image

So, it seems you are right with, but what can I do to speed it up?

EDIT: I also discovered a huge memory amount which successively increases during startup. It ends at ~500mb.
This function seems to be the root of that evil path:

EDIT2:
I had a look into the RTTITypeBase* IReflectable::_getRTTIfromTypeId(UINT32 rttiTypeId) function and it looks like you could improve it by a good amount. I don’t think a std::stack with an internal std::deque will be the best option for your needs. I rewrote the function with a std::vector and instead of 35 seconds on startup it only took me 25 seconds!
Here is my version; the commented code is your old version:

RTTITypeBase* IReflectable::_getRTTIfromTypeId(UINT32 rttiTypeId)
{
	//Stack<RTTITypeBase*> todo;

	//for(const auto& item : getDerivedClasses())
	//	todo.push(item);

	auto todo = getDerivedClasses();
	while(!todo.empty())
	{
		/*RTTITypeBase* curType = todo.top();
		todo.pop();*/
		RTTITypeBase* curType = todo.back();
		todo.pop_back();

		if(curType->getRTTIId() == rttiTypeId)
			return curType;

		/*for (const auto& item : curType->getDerivedClasses())
			todo.push(item);*/
		auto& newTodos = curType->getDerivedClasses();
		todo.insert(std::end(todo), std::begin(newTodos), std::end(newTodos));
	}

	return nullptr;
}

In the end, it could be even better via recoursion. Perhaps I’ll do an other version :wink:

PS: I know, profiling in debug mode isn’t the very best, but even in release mode it seems to be faster than your version.

EDIT3:
I tried it in the recoursive way and I were able to load the screen in less then 13 seconds, which means ~1/3 of the time of the first version. Here you go:

RTTITypeBase* _recoursiveGetRTTIfromTypeId(UINT32 rttiTypeId, Vector<RTTITypeBase*>& typeCollection)
{
	for (auto item : typeCollection)
	{
		if (item->getRTTIId() == rttiTypeId)
			return item;
		if (auto type = _recoursiveGetRTTIfromTypeId(rttiTypeId, item->getDerivedClasses()))
			return type;
	}
	return nullptr;
}

RTTITypeBase* IReflectable::_getRTTIfromTypeId(UINT32 rttiTypeId)
{
	return _recoursiveGetRTTIfromTypeId(rttiTypeId, getDerivedClasses());
}

#6

Thanks for investigating. It still shouldn’t take that long, but since that function really doesn’t do any heavy lifting except for doing dynamic memory allocations (which you are right about, are redundant) I can conclude that your slowdown is caused by the debug heap. Debug heap is about 20x slower than the normal heap, but even then your slowdown seems to be much worse than that. I’d confirm you don’t have any advanced heap debugging flags enabled (like recording a callstack on every allocation).


#7

I assume the framework loads all those data files located in the /data folder at StartUp. Is there a way to prevent this? There are many assets which are obviously necessary for the Bashee3D editor, but not for the framework itself. At least those shaders seem to be the reason for this long time frames.


#8

Data folder keeps assets needed for the framework, editor assets are not kept there.

Shaders have been problematic lately as their numbers have grown a lot, and different shader permutations end up storing a lot of redundant data. This is due a refactor but I’m not sure when I’ll get around to it. There might be quick optimizations to be done in the serializer code to speed things up.