# Platform Support Library (`platform`) ## Table of Contents * [Home](./CONTENTS.md#planning-documentation-for-fennec) * [Platform Support Library (`platform`)](#platform-support-library-platform) * [Table of Contents](#table-of-contents) * [Introduction](#introduction) * [Implementation](#implementation) * [Consoles](#consoles) ## Introduction   The platform support library will include headers, functions, and classes related to supporting various platforms. Platforms may be defined as any Hardware, OS, or Drivers that must be initialized for the engine context. ## Changes   For the foreseeable future, I will be switching to SDL for window management. SDL was chosen over GLFW due to GLFW's lack of support for Android and iOS. A custom implementation is still something I would like to do, but is currently out of scope for where I would like to focus my energy. As soon as SDL becomes ## Implementation Platform Support will be implemented in the following order: - Linux/BSD - Wayland - OpenGL (EGL) ✅ - XKB - PulseAudio - Vulkan - X11 - ALSA - Vulkan - Microsoft Windows - XInput - OpenGL (WGL) - WASAPI - Vulkan - Android - OpenGL ES - AAudio - openslES - macOS/iOS - cocoa - OpenGL - Core Audio - Vulkan - Metal   Linux Wayland will be implemented first. Once setup, the core engine will be implemented and tested on top of Wayland. Once the engine is in a stable state, then support for other platforms will be resumed. ## Consoles   Most consoles will never get official platform support due to NDAs which conflict with the principles of this engine. fennec will avoid using proprietary libraries except when strictly necessary, such as support for Windows and MacOS. fennec will interact with any drivers required for the listed operating systems above, even if proprietary. ## Notes We want this system to be fairly modular, renderers and their respective gfxcontext implementation should be a drop-in, as well as window implementation. This is a fairly complex problem to solve, especially since most display protocols have their own specific implementation for supporting different contexts. To illustrate this problem, let's say we have SDL and OpenGL implemented. If we were to add Vulkan, there are Vulkan specific functions for creating a window compatible with SDL, i.e. SDL_Vulkan_CreateSurface. Who should know how to implement this function? How do we define the API so that we do not have to modify existing classes to add Vulkan support? The easiest solution to this problem is template functions. We can have a template that takes a Renderer type as a template parameter, then initialize the window for that. Now, if someone wants to create a Vulkan renderer, all they have to do is write an overload for the template function. This can be neatly wrapped up in a single C++ file. Only the gfxcontext implementation has to know of this function's existence since it will be the one calling the function. The main drawback with this implementation is an outside observer calling the template function directly. Only the one C++ file knows of its existence. Template functions are inlined after all. There are two options to solve this, the ``[[noinline]]`` attribute, or we simply scope protect the function and create it purely from a "driver" standpoint. We can register drivers with the platform, then retrieve a list of drivers with a specific type, e.g. glcontext, then the type aware implementation is isolated to the C++ file associated with glcontext, and glcontext registers itself with the platform. We can give drivers a priority so that Vulkan, a more modern and "more powerful" renderer is chosen first, if available, and falls back to OpenGL. Now we run into the issue of, what if we want to implement Vulkan and Wayland separately? These implementations will be part of the core engine, but let's take a more contrived example; X-Box and Playstation. X-Box and Playstation have their own protocols for display rendering, but both use DirectX. Say someone implements a DirectX api for Desktop computers, then someone else implements a windowing system for X-Box or Playstation. If another user wants to use DirectX with X-Box/Playstation, they will have to write their own overloads for that implementation. The only viable solution for this problem is to rely on the Open Source community. Pray that someone finds both engine extensions and writes the overloads for you. This might sound very familiar to modders, and this is my intention with this engine. Pieces should be modular, and should be easily connected when two non-dependent systems have underlying interdependencies. There is one more option that I have come up with; mapping type ids. The implementation of typed.h generates type ids *at runtime* which allows us to map a pair of ids for this purpose. We can use a pair of window and gfxcontext uuids to determine the loading functions. All we would need to do is register a function that takes a window as an arguments and constructs the gfxcontext. We can combine this with the above to allow scoped access to the classes if that is needed.