On iOS, the main thread does framebuffer operations just before it requests a rerender of the view contents. This means that GL operations on the Map thread will interfere with that and cause a crash. While most GL operations happen throughout rendering (which is synchronized with the main thread), deletion of shared_ptrs release in turn their OpenGL objects. This may happen at any time and isn't synced with rendering.
This patch changes this so instead of deleting all objects immediately, we are collecting all abandoned IDs and delete them in bulk once the main thread has given us permission to use OpenGL calls (i.e. during render()).
We are also removing the code that is passing the Environment around
and instead, we get now the Environment in the TileData using
Environment::Get().
When processing the job, the work will be temporally registered to
the Environment as "TileWorker_0/0/0" which can be used for logging
in the future. At the end of the job, it gets unregistered
automatically from the Environment.
The Environment will now keep track of every thread that is running
within a Environment::Scope. Once the Scope object is created, it will
automatically register the thread to the ThreadInfoStore with some
additional information and it will automatically deregister as the stack
frame rewinds (which can be useful for Threads that are temporally in
use by an Environment like Workers).
The ThreadInfoStore could be using the thread-local storage, but I think
that making the Environment aware of what threads are associated to it
can be useful for writing a mechanism for posting messages between threads.
Withing a Scope, the Environment associated to the thread can be queried
at any time which will save us from juggling a reference to the
Environemnt around. Finally, the type of thread (Main, Map, etc) can
also be queried at any moment to make sure a piece of code is running
on the desired thread.
we are now scoping all file requests to an environment object. The FileSource implementation treats
this as an opaque pointer, but allows canceling all Requests that are associated with that pointer.
This is necessary to abort all file requests that originated from a particular Map object. Aborting
a file request is different from canceling a file request: A canceled request doesn't have its
callback called, while an aborted request will have its callback called with an error, indicating
that the environment is going to be shut down.