-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Bucket enhancements to allow property-only update #2812
Conversation
var group = groups[g]; | ||
var length = group.layout.vertex.length; | ||
var vertexArray = group.paint[layer.id]; | ||
vertexArray.resize(length); | ||
|
||
var start = g === startGroupIndex ? startVertexIndex : 0; | ||
var end = (endVertexIndex && g === endGroupIndex) ? endVertexIndex : length - 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With this method now accepting ending indexes, maybe it would be simpler require the end index params and move the responsibility for choosing group.layout.vertex.length - 1
out to the callers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense 👍
👀 |
Nice! What's up with the build failure — needs test updates as well? |
@mourner Yep, tests needed small tweak. Just fixed in a556c97 along with the change to populatePaintArrays mentioned above |
Ah, looks like some rendering tests are still broken. Will check those out soon. |
@lucaswoj @mourner ^ the last few commits clean things up as follows:
|
Removing "WIP" from the title now -- let me know if you think the changes in |
// source-layer-name: [{ /* feature 0 properties */}, {/* feature 1 properties */}, ...], | ||
// another-layer-name: [...] | ||
// } | ||
// where feature 0, 1, 2 are the features, in order, in this vector tile. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this comment be reformatted into JSDoc like rest of the code, while moving the note to a ticket or GH comment? It looks a bit like a TODO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah @mourner sorry I wasn't clear in the comment--my intention was actually to revert this change entirely, excluding it from the PR and keeping the changes scoped to the Bucket classes. That's what I meant by "this might make more sense as part of a custom source type".
I guess a downside to that is that the dds_update_bucket
benchmark would also have to go.
If yall think it's worth keeping this here, though, I'd be happy to clean it up (including the comment, as you said), and also to add some tests for it.
In preparation for a rebase, preserving some inline comments: @mourner commented about fixing/removing the TODO-like comment above
cc @lucaswoj for you to weigh in |
6bb6b8d
to
0002bb3
Compare
I'm finding that there are some problems here relating to the arrays getting "transferred" from the worker back to the main thread after the initial load/parse: Transferring apparently leaves the array "neutered" in the worker thread, so that it can't be updated. Moreover, when the bucket is reconstructed on the main thread, the transferred/serialized |
Yeah, that's the point of transferring — moving data fast between threads without copy, but at the expense of not being able to access it after it was moved. |
Yeah, makes sense. I'm thinking I'll play with either (a) transferring the I think either of these will require reconstructing the "arrayGroups" On Sun, Jul 10, 2016 at 3:07 AM Vladimir Agafonkin [email protected]
|
0002bb3
to
239ef7a
Compare
|
||
Bucket.prototype.populatePaintArrays = function(interfaceName, globalProperties, featureProperties, arrayRange, featureIndex) { | ||
if (typeof featureIndex !== 'undefined') { | ||
this._featureIndexToArrayRange[featureIndex] = arrayRange; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It occurs to me that this map should actually be this._featureIndexToArrayRange[interfaceName][featureIndex]
@lucaswoj Soon I will rebase to bring this up to date with the refactor in #2865; before I do, would love to get your 👍 / 👎 on each of the following changes that are currently included here:
Number 4 raises a broader question: originally, I only included it so that yall could check out the benchmarks and such, assuming that in the end we would remove it and leave that logic as the responsibility of the dynamic-property-updating custom source implementation. But this does require that custom to reach pretty far into the GL JS's implementation details. Is this okay? Would it be better to perhaps include |
Sounds good 👍
Sounds good 👍
This sounds potentially problematic. What happens if the main thread tries to render the bucket while its arrays are "missing"? Is it possible to create a fresh paint array with the new data without transferring anything from the main thread back to the worker? I can't think of any reason why we'd need to read from the original paint arrays or why we have to use the same
I would prefer to refrain from making this a public API. You may add this code and use it for your vector tile property updater but we do not plan to provide support for or make any external promises about the stability of this API. |
Thanks @lucaswoj !
Doh! I hadn't thought of this.
Yeah, it does seem like this should be possible. Since we'd be talking about creating new paint arrays but not the corresponding "layout" arrays, doing this might involve some tweaks in a couple places, but pretty minor, I think.
👍 this makes sense and sounds reasonable to me. |
5cfc637
to
d085e67
Compare
Rebased (previous: 5cfc637)
Also updated to reflect this suggestion, removing Next steps:
|
The tests now in place for Bucket#updatePaintVertexArrays, Bucket#updatePaintVertexBuffers, and WorkerTile#updateProperties should have this covered. |
927c8d9
to
a8fffd9
Compare
Rebasing to keep up with master. Previous head is 927c8d9 Branchload-multiple-maps: 250 ms, loaded 6 maps. Masterload-multiple-maps: 864 ms, loaded 6 maps. |
Bucket enhancements to allow property-only update
Hey folks, I spoke with @ryanbaumann at my office a few days ago regarding some performance issues that I'm having with using mapbox-gl-js. He pointed me at this PR as a starting place for trying to improve hover / selection performance on maps with large numbers of geojson elements (40k is a reasonable target). I've been doing some work based off of this PR, but it doesn't rebase cleanly against 0.24 anymore. I totally understand that this exact code probably won't be what gets merged into the mainline eventually, but is this a total fools errand? I'm primarily concerned about getting stuck permanently on my 0.22 fork if this gets abandoned. Andy |
I cannot speak to @anandthakker's plans to maintain this branch. We have plans to enable functionality like the functionality implemented in this pull request through custom source and layer types (#281 #2982 #2982). I suspect the final form of this feature will involve simplification of GL JS's architecture and emphasize object composition as the preferred way to create custom sources. If you are looking for a way to improve the performance of hovering and selection, I recommend looking at #2874, other |
Based on the most recent discussion in the PR here, I don't expect that this branch is going to make it into master. The work here was motivated by a project we're working on that requires joining changing property data with geometries provided by vector tiles. As discussed here, this is actually already possible via the 'custom source' interface, although that interface is likely to change as part of the architecture simplifications that @lucaswoj mentioned, and so isn't yet publicly documented. @AndyMoreland I'll be open sourcing our approach to this, but it's going to take a few weeks due to constraints beyond my control. |
Thanks for the update, both of you. It sounds like I should hold off for a bit on this until you get the new APIs standardized. |
Linking to the |
Closing this as "stale." We are working on a slightly different approach, allowing custom sources which adhere to a specific interface, here: https://github.com/mapbox/mapbox-gl-js/projects/2. |
@lucaswoj I've been experimenting a bit with the "join new properties to existing geometries" problem. As you've suggested when we've discussed this, a couple of key enhancements to
Bucket
will be needed:populatePaintArrays
-- currently, this method only takes a starting index and assumes that it should update from that index to the end of the current arrays, which makes it only suitable for populating the arrays the first time. Adding an end index parameter would make it straightforward to make updates to an already-populated array.This PR includes draft versions of those changes, along with:
updateProperties
method, which I stuck ontoWorkerTile
just for demo/prototyping purposes (but which should in reality probably go into a custom source type that encapsulates the data-joining/updating)dds_parse_bucket
anddds_update_bucket
-- to get a quick-and-dirty estimate of the perf gains from just updating versus a full parse. Results are pretty good at time of posting this = approx 43% gain: