-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Fix requestRender condition in DataSourceDisplay.update #12630
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
base: main
Are you sure you want to change the base?
Conversation
Thank you for the pull request, @Beilinson! ✅ We can confirm we have a CLA on file for you. |
I don't want to revert the change from #12429 as to me that does seem like a logical change (if the I originally didn't think it correct to add an additional flag, however upon further investigation I understood that the former logic prior to #12429 scheduled a render whenever TL;DR - returns the previous logic by adding a new flag instead of undoing the changes on the |
I'll point out that with this fix, requestRenderMode reverts to the previous behavior where renders are only requested after all datasources under the DataSourceDisplay finish asynchronous work. This can actually cause delays in rendering, if for exampling 1 datasource finishes after 2 frames, while another takes significantly more, a render will be requested only after the longer one finishes. I could alter this behavior if desired |
Thanks for working on this patch @Beilinson, much appreciated. We also noticed this regression breaking our app (that uses request render) when updating from 1.121 to 1.128, I think it snuck in with 1.126 as noted in the We have confirmed that your first commit 9d2fe69 fixes our issue (we patched it on top of 1.128), we have not yet tested your commit bd38955 In terms of the second commit, is that what causes the delays in rendering you mentioned above ? Let us know if there is something we can do to help out. |
Glad I could help @jasonmprop, The second commit is a more technically correct fix, from what I can see more or less the |
Theres actually an interesting alternative fix which can change how if (this._prevResult !== result) {
this._scene.requestRender();
} Then a frame render will be requested twice when the async work begins and when it finishes, which will allow for things like updating an entity property, or adding an entity to a scene to be rendered automatically (without manually calling While this is not consistent with the https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/ blog post by @ggetz, I think this is worth considering:
|
bcf933c
to
492537a
Compare
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.
Thanks for your patience here @Beilinson.
Then a frame render will be requested twice when the async work begins and when it finishes, which will allow for things like updating an entity property, or adding an entity to a scene to be rendered automatically (without manually calling requestRender()), while still keeping renders to a minimum when the scene is unchanging.
I like this idea! However, as I mentioned in my review comment, I'm concerned that allowing the billboard visualizer to go back to returning false
after return true
breaks some existing behavior.
Maybe we're conflating ready
and the return value of update
with too many things. Maybe visualizers should expose a separate property for tracking updates requiring a re-render?
@@ -226,6 +228,7 @@ BillboardVisualizer.prototype.update = function (time) { | |||
time, | |||
defaultSplitDirection, | |||
); | |||
ready = billboard.ready && ready; |
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.
I think this "undos" the fix in #12429, as this function can now return
true
one frame, then false
when the billboard is loading, then true
again when it's completed.
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.
This should be fine, update returns whether or not any processing is finished, while ready is stored separately on the datasourcedisplay and stays enabled after the first time
The naming is conflated internally in the update function here, I can change that
@ggetz I have some concerns that the changes here (to fix #12543) will introduce excessive rendering when the system creates new Billboard entities very often. #11820 - This was the original bug report that was caused by some of the logic in the Billboard's _loadImage function. Essentially, it always requested a render when the Billboard's image loaded which would cause a render every time a new Billboard entity was created. I believe the best tradeoff here would be to have the Billboard load its image from the TextureAtlas synchronously if the image id is already in the TextureAtlas. Otherwise, the image should be loaded asynchronously and then a render should be requested immediately after the image is resolved. This allows users to reuse images in request render mode without introducing unnecessary render cycles while still fixing the problem with Label backgrounds failing to render after "missing" their target frame. I had identified a workaround to #11820 that essentially implemented this behavior by passing a "redraw" parameter to the completeImageLoad function that was defined in Billboard.js:
Would we be able to implement something similar with the new code structure? |
// Request a rendering of the scene when all of the data sources | ||
// switch from false to true | ||
if (!this._prevResult && result) { | ||
this._scene.requestRender(); | ||
} | ||
this._prevResult = result; |
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.
This code will effectively request a render each time a Billboard Entity is created because of the way the timing works with the new TextureAtlas implementation.
I believe an alternate solution is necessary since this is not consistent with the advertised behavior of requestRenderMode (read my 2nd comment on #11820 for more info).
I commented on the PR thread and suggested that it may be feasible to synchronously load the texture if the id already exists in the TextureAtlas. Then, for images that are not in the atlas, asynchronously load the image and then request a render once it has loaded. This will effectively request a render once per distinct image and then for all subsequent uses of the image, invokers may simply request a render after creating the Billboard since the image will load synchronously.
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.
Another alternative to think about is the possibility of introducing a callback mechanism from the Billboard Entity API to allow invokers to pass some code to execute once the image is loaded.
To address #11529, the Label Entity's default implementation could pass a callback that requests a render. Then, for Billboard Entities, invokers may choose to request a render (or not) when the Billboard finishes loading. This may be a good balance to preserve the advertised behavior of requestRenderMode while also addressing #11529 without introducing excessive render requests.
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.
Great insight, I've been playing around with this idea locally and it seems to work well, will iron it out and commit soon
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.
Any luck with either of these paths?
Description
Fixes the requestRenderMode issue which stems from #12429.
Issue number and link
Fixes #12543
Testing plan
Sandbox Example
The setTimeouts are so that the scene is definitely NOT requesting any render when updating the polyline material (all the tiles should already be loaded in).
With the above test the bug is easily reproducible, and is fixed with my branch.
Author checklist
CONTRIBUTORS.md
CHANGES.md
with a short summary of my change