-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Asynchronous rendering #8820
Comments
Related (follow-up) work on Android to implement |
Summary of the task of splitting |
What is not clear from this design is how something like "query rendered features" is going to work synchronously. We need the "evaluated" state for that, right? |
@tmpsantos Very good question. ATM I see two options:
We can support both of course, but moving to the later would have my preference. |
I did a rough dry run at splitting
I'm continuing to work on prerequisites for the ℹ️ items, but I could use help on the others. |
I will take care of that while looking at the
Depending on the concurrency model / necessity, we could retain this. I was imagining re-using the actor model for communication between Style/RenderStyle. In this case we can propagate these messages back from RenderStyle to Style. I'm finishing up the Light changes you requested now and then will start to pick up the items you list one by one. |
Looking into cutting up the SpriteAtlas; it seems that we would need a way for the We should pass the |
No, communication is one way; there's no communication in Like it's responsible for loading source TileJSON, |
I added a write-up of lifetimes and object ownership in |
I've been keeping a list of potential followup changes. These are things that I've noticed when working on this that would be nice to do at some point but so far aren't directly necessary:
|
We want to be able to offload rendering onto a separate thread to free up the main thread on some platforms (most notably Android and Qt). The main thread should, as much as possible, be used only for user input and drawing so that a high frame-rate can be maintained.
A lot of work is already delegated to dedicate workers, but in order to offer a smooth experience on somewhat more lightweight hardware we need to eliminate some of the processing currently done on the main thread. Most notably:
Not all platforms need/should use a separate thread for rendering, so we want to enable a model where either is possible. Also, as an additional hurdle, on some platforms we want to be able to integrate with existing platform specific solutions such as the GLSurfaceView which come with a dedicated render thread that prohibits the use of a run loop as it blocks on a mutex.
In order to support this, we probably need a model where we utilise three threads:
Eg. Something like (very high-level):
Preparation
Currently a couple of classes contain data that is needed on both the main thread (to offer our public, synchronous api) and on the would-be render thread. In preparation of supporting a render thread these classes need to be split up accordingly. In the case of Layers and Sources, we've decided to aim for a model where we have a parallel tree of Render items which have a reference to their counterpart's immutable implementation class.
Related:
Currently underway
GlyphAtlas
callbacksLayer::Impl
andSource::Impl
subclasses immutable so they may be shared between style and render layers/sources [core] Immutable style Impls #8929add
/remove
/getImage
and thestyle::Image
map itself toStyle
, and makeStyle
responsible for loading the sprite PNG and JSON, parceling out the individual images, and filling up the map.GlyphAtlas
will belong toRenderStyle
, which won't be able to propagateonGlyphsLoaded
/Error
messages to a parent observer. Investigate whether this is necessary/how to eliminate. (Likely do the same foronSpriteLoaded
/Error
for consistency, even though it could be preserved.)lastError
used for? Should it belong toStyle
orRenderStyle
exclusively, or does it need to be split?TileParameters
will have aRenderStyle
reference rather than aStyle
reference.GeometryTile
will need to iterate overRenderLayers
rather thanLayers
, obtain an immutableImpl
for each, and pass them to the worker rather than a copy of theLayer
.SpriteAtlas
will need access to images (by immutable reference).renderSources
andrenderLayers
(insetJSON
and{add,remove}{Source,Layer}
) withupdate
-time updates based on diffing immutables.updateBatch
mechanism with immutable layer diffing ([core] Omnibus: Split RenderStyle from Style #9119)Style
andRenderStyle
needisLoaded
anddumpDebugLogs
methods. In the places that callStyle::isLoaded
, add a call toRenderStyle::isLoaded()
; likewise fordumpDebugLogs
. ([core] Omnibus: Split RenderStyle from Style #9119)GlyphAtlas
will need access to a glyph URL (by immutable reference). ([core] Omnibus: Split RenderStyle from Style #9119)update
will move toRenderStyle
. Replace direct access to sources, layers, images, transition options, classes, and light with immutable references passed viaUpdateParameters
. ([core] Omnibus: Split RenderStyle from Style #9119)FileSource
using actors (Convert DefaultFileSource and dependents to actor model #7678), or otherwise makeDefaultFileSource
threadsafeAnnotationManager
to use runtime styling APIs (Reimplement MGLAnnotation atop MGLSource and MGLStyleLayer #6181), or otherwise make it threadsafe Mutex guard annotation manager for cross thread usage #9220GeoJSONSource
's use of GeoJSONVT and Supercluster is threadsafeRenderer
/Renderer::Impl
pair:std::unique_ptr<Renderer>
provided by coreRenderer::Impl
to hide details from public headerRenderer
methods:update(const UpdateParameters&)
(UpdateParameters
forward declared)render(const RenderParameters&)
(RenderParameters
forward declared)Painter
andRenderStyle
intoRenderer::Impl
setRenderer(std::unique_ptr<Renderer>)
(might be null to "reset" renderer during shutdown)update(std::unique_ptr<UpdateParameters>)
render(std::unique_ptr<RenderParameters>)
Renderer
either immediately (synchronously) or via sending message to rendering thread (asynchronously)Renderer
to trigger a re-render when needed (animation)RenderStyleObserver
/MapObserver
notificationsNext steps
RenderFrontend
for AndroidRenderer
if we lose the context. The alternative is to keep a copy of all bucket data in main memory, so that we can recreate the GL buffers from it. This would ~2x the memory usage of maps, just to get somewhat faster reloads when the context comes back -- not worth it IMO.cc @mapbox/gl
The text was updated successfully, but these errors were encountered: