The silent refactor

I’ve been busy. Very busy. The year is coming to its end and I had the need for one more refactor. One big refactor. One that has been in my list for quite some time. And I called it the “silent” refactor.

As my other project is moving forward, so are the needs for new things. Improved text rendering, shadows, better input methods, physics… Alas, most of the newest features had some kind of impact in the general performance of the engine. And at some point the game was no longer playable at 60fps.

Enters the silent refactor: a series of low-level changes with a single purpose in mind: improving performance. While I tried to avoid changing the high-level APIs, some of them got broken in the way because of the updates. For example, I went back to using C++ smart pointers and the majority of the function signatures got changed as a side effect. It wouldn’t have been fun otherwise 😉

Anyway, the biggest change of all is probably multithreading support. Yes, I just said the “M” word. Simulations now run in two threads: one for window management, rendering and input stuff and another thread for the actual simulation pass, including updating components and physics.

The render pipeline suffered some adjustments too. Now it’s material-centric, meaning the render queue organizes primitives based on the material they’re using, thus avoiding a lot of redundant draw calls due to state changes. This is a huge performance gain if there are several objects sharing materials or primitives.

Maybe the most visible change is the support for Retina displays in OSX. There was an aliasing problem in older versions caused by a difference between the window size and the frame buffer size. For Retina displays, the later is twice the size of the requested window size. So, for example, a 1280×720 window size needs a 2560×1440 frame buffer in retina-based monitors. The fix required me to upgrade GLFW to the latest version, which had some side effects in other subsystems, but nothing too worrisome.

The code is a bit unstable as I still need to clear some concurrency issues, but the performance gain is noticeable. Even with shadows enabled, the simulation is back to 60 fps.

That’s all, folks. The last refactor of 2014.

Happy New Year!