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

Share webGL contexts between layers #942

Closed
manthey opened this issue Oct 18, 2018 · 6 comments
Closed

Share webGL contexts between layers #942

manthey opened this issue Oct 18, 2018 · 6 comments

Comments

@manthey
Copy link
Contributor

manthey commented Oct 18, 2018

Currently, having more than 15 webgl layers will exhaust the available webgl contexts. If webgl layers do not have non webgl layers between them by z-index, a single context can be used instead. This should be done automatically. When there are multiple layers, the webgl renderer will need to apply opacity for each layer, rather than using the opacity on the div.

manthey added a commit that referenced this issue Nov 2, 2018
Move the layer specification to a typedef for better documentation.
Make sure all layer types use typedefs.

Fix issues with the layer id function.

Ensures that canvas and renderer can actually be specified when creating
a layer.  This allows layers to share a renderer or a canvas.  For the
webgl renderer, sharing a canvas results in flashing, as each layer
completely redraws the canvas.  When sharing a renderer, there is no
proper support for opacity (probably not for visibility) or z-order, but
this is a first step to implementing #942.

Removed some unused code.
@manthey manthey mentioned this issue Nov 2, 2018
manthey added a commit that referenced this issue Nov 2, 2018
Move the layer specification to a typedef for better documentation.
Make sure all layer types use typedefs.

Fix issues with the layer id function.

Ensures that canvas and renderer can actually be specified when creating
a layer.  This allows layers to share a renderer or a canvas.  For the
webgl renderer, sharing a canvas results in flashing, as each layer
completely redraws the canvas.  When sharing a renderer, there is no
proper support for opacity (probably not for visibility) or z-order, but
this is a first step to implementing #942.

Removed some unused code.
manthey added a commit that referenced this issue Nov 2, 2018
Move the layer specification to a typedef for better documentation.
Make sure all layer types use typedefs.

Fix issues with the layer id function.

Ensures that canvas and renderer can actually be specified when creating
a layer.  This allows layers to share a renderer or a canvas.  For the
webgl renderer, sharing a canvas results in flashing, as each layer
completely redraws the canvas.  When sharing a renderer, there is no
proper support for opacity (probably not for visibility) or z-order, but
this is a first step to implementing #942.

Removed some unused code.
@manthey
Copy link
Contributor Author

manthey commented Dec 3, 2018

Regarding shared webgl contexts, layering, and opacity.

When two layers share a webgl context, I intend that they will also share a depth buffer. This will be a difference between separate contexts and shared contexts (but, when we support full 3D, I view this as a positive feature).

On tile layers, we render different levels of tiles at slightly different z values, all "just behind" their actual z value. When we share contexts, multiple tile layers will composite as expected (with layers with higher layer z-indices just above those with lower). If the shared context has both tile and feature layers, then features with the same z value as tiles will always appear above the tiles, even if the tile layer's z-index is above the feature layer's z-index. To do otherwise, we could either avoid sharing contexts between tile and feature layers OR there will need to be slight z offsets for all layers (not just tile layers) to force them to composite properly. I think that, for now, we just accept that when tile and feature layers share context, tiles are behind features with the same z value regardless of layer z-index.

Sharing context between layers with different opacities is tricky. The results of changing feature opacity instead of layer opacity is not the same (for instance, a layer with 100% opacity and overlapping lines each with 50% opacity will form an area with 75% opacity, whereas a layer with 50% opacity and overlapping lines with 100% opacity will have everything at 50% opacity). Either we will have to render each layer into a frame buffer object or not share contexts between layers with different opacities.

For automatic merging of shared webgl contexts, I think the simplest approach would be to only share contexts between adjacent webgl layers that have the same opacity (and layers with 0 opacity or 0 visibility could be shared, too, as they will skip rendering).

Feedback welcome, as I am about to add code for automatic sharing of webgl context between adjacent webgl layers.

@matthewma7
Copy link

Hi @manthey, this all sounds reasonable to me.
Are you thinking about providing an option to enable context reuse or always reuse? Just asking, I know it could be a lot more work to make it optional.

@manthey
Copy link
Contributor Author

manthey commented Dec 4, 2018

I am thinking that context sharing would be optional.

Currently, you can either create a layer and have it create a renderer instance or you create the layer while specifying an existing renderer instance. In the second case, layers share the context. This works correctly on my development branch except for honoring opacity and visibility properly.

I am thinking that if you create a layer without passing an existing renderer instance and a flag (canShareContext?) were set, that renderer instances would be shared where possible. I think that this would be the default, so you would have to explicitly clear this flag to avoid auto-sharing contexts.

As I mentioned above, I think contexts would only be shared if the opacity were the same value. This means that if you have three layers A B C that are using one context and adjust the opacity of layer B, you would end up with three separate contexts. I think this is simpler than implementing frame buffer objects, but could be confusing if someone is using the shared contexts to use a single z-buffer for 3D purposes.

@matthewma7
Copy link

Got it, thanks for the answering. 🙂

@manthey
Copy link
Contributor Author

manthey commented Jan 3, 2019

I've got a local branch where this all works, but it requires a minor update to the vgl package: OpenGeoscience/vgl#106. Once that gets merged and a new vgl release made, I'll make a PR to finish this.

@manthey
Copy link
Contributor Author

manthey commented Apr 3, 2019

Resolved in #975.

@manthey manthey closed this as completed Apr 3, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants