Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify Bucket architecture #2875

Closed
lucaswoj opened this issue Jul 14, 2016 · 4 comments
Closed

Simplify Bucket architecture #2875

lucaswoj opened this issue Jul 14, 2016 · 4 comments

Comments

@lucaswoj
Copy link
Contributor

The hierarchy of objects in our data system roughly looks like this:

Tile -> Bucket -> program interface -> array group -> layout and paint arrays

We could simplify by collapsing the hierarchy to:

Tile -> TileLayer

There would be a 1:1 correspondence between TileLayers and calls to drawElements. All information that was previously stored in the object hierarchy would be stored within TileLayer.

class TileLayer {
    programInterface: ...
    layoutArray: ...
    vertexArray: ...
    paintArrays: ...
    ...
}

We could also factor all TileLayer creation logic (i.e. addFeature) out into a new set of TileLayerFactory classes. This functionality is only used within the workers.

@jfirebaugh
Copy link
Contributor

Definitely in favor of improving the architecture of rendering data if we can find a simpler design that still satisfies all our requirements. Here are some requirements that the existing hierarchy satisfies that we'll want to preserve in some way:

  • One of the functions of Bucket is to share layout vertex and element arrays between layers which have a parent/child ref relationship. We should retain this sharing even if we eliminate the explicit "bucket" level in the hierarchy.
  • The "program interface" level was introduced in support of symbol layers, which use multiple vertex arrays with different shaders to render glyphs, icons, and debug collision boxes. Removing this level of the hierarchy would definitely simplify the other tile/bucket/layer types, but might require significant changes to how symbol layers are rendered.
  • The use of "array groups" is required by inherent limitations of WebGL. We have to loop over groups at some point in the rendering pipeline, but at the same time we benefit from having the rendering work that's invariant over the groups in a given tile -- e.g. setting up uniforms -- live outside that loop. In other words, as with Bucket, there are performance reasons why we ended up with the current hierarchy, and we'd need to find a way to preserve that.

@lucaswoj
Copy link
Contributor Author

One of the functions of Bucket is to share layout vertex and element arrays between layers which have a parent/child ref relationship. We should retain this sharing even if we eliminate the explicit "bucket" level in the hierarchy.

We can have multiple TileLayers reference the same ArrayBuffers without any transfer performance penalty. Instead of having an explicit object heirarchy relationship between TileLayers in the same ref family, TileLayers in the same ref family will reference the same ArrayBuffers.

The "program interface" level was introduced in support of symbol layers, which use multiple vertex arrays with different shaders to render glyphs, icons, and debug collision boxes. Removing this level of the hierarchy would definitely simplify the other tile/bucket/layer types, but might require significant changes to how symbol layers are rendered.

My vision is that each TileLayer will correspond with one draw* call. TileLayers are strictly ordered. This will give us sufficient expressive power to represent the current symbol layer rendering paradigm.

The use of "array groups" is required by inherent limitations of WebGL. We have to loop over groups at some point in the rendering pipeline, but at the same time we benefit from having the rendering work that's invariant over the groups in a given tile -- e.g. setting up uniforms -- live outside that loop. In other words, as with Bucket, there are performance reasons why we ended up with the current hierarchy, and we'd need to find a way to preserve that.

My hope is that implementing #145 (or a subset of this functionality) will give us the ability to do efficient GL state mutations while reducing the complexity of Bucket et al.

@anandthakker
Copy link
Contributor

I too would love to see a simpler design here!

In addition to the requirements @jfirebaugh raised (and @lucaswoj addressed) above, another thing that I think we should keep in mind is that the current 'conceptual parity' between GL JS and GL Native is a major advantage. I would be very hesitant to introduce divergence, especially for something as complex and central as our system for creating and managing rendering data buffers, and so I think we should consider both platforms as we work to make progress on this design.

@jfirebaugh
Copy link
Contributor

This area of the code has gone through many rounds of refactoring, and is in a fairly decent state these days.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants