Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Strict render step to Map::render{Sync,Still} #2207

Closed

Conversation

brunoabinader
Copy link
Member

First, a little background: Map context thread is responsible for two main tasks:

  1. Update render objects.
  2. Render objects to screen.

Such tasks are independent and can be pipelined. However, only task 1 can be called asynchronously, while task 2 needs to be done synchronously. Currently we have the following issues:

a. Task 1 causes 2 to be done outside of view invalidation call. Instead, we should always render inside view invalidation call.
b. Task 1 has to be manually triggered via Map::nudgeTransitions() when a transition/animation is in progress. Instead, map context should be smart enough to trigger task 1 asynchronously after completion of task 2.

With that in mind, I propose the following fixes:

  • Get rid of Map::nudgeTransitions; Render updates (step 1) are now asynchronously triggered by MapContext::renderSync whenever required.
  • Get rid of MapData::{get,set}NeedsRepaint; This synchronisation flag is no longer required as MapContext should be robust enough to asynchronously trigger a view invalidation (step 2) if a transition/animation is in progress.
  • Provide an asynchronous handler for view invalidation in MapContext. This is handy because while step 2 needs to be done synchronously between Map and MapContext threads, view invalidation itself can happen asynchronously.
  • Because transform transition updates only in Map thread, Map::renderSync may call for Map::update to trigger an asynchronous update if Transform contains a transition in progress.

/cc @tmpsantos @jfirebaugh @kkaefer @incanus

@brunoabinader brunoabinader added iOS Mapbox Maps SDK for iOS performance Speed, stability, CPU usage, memory usage, or power usage macOS Mapbox Maps SDK for macOS Android Mapbox Maps SDK for Android Linux refactor and removed in progress labels Aug 30, 2015
@brunoabinader brunoabinader force-pushed the 2207-strict_render_step_to_map_rendersync branch 3 times, most recently from dd6702f to a96c73b Compare September 1, 2015 11:03
@brunoabinader
Copy link
Member Author

Tested on Android (Samsung Galaxy S5) and iOS (iPad mini) 👍

@brunoabinader brunoabinader force-pushed the 2207-strict_render_step_to_map_rendersync branch from a96c73b to 5c81c4a Compare September 1, 2015 14:43
@friedbunny
Copy link
Contributor

This looks fine to me on iPhone 5 — user dot appeared to behave properly and update as expected.

@incanus
Copy link
Contributor

incanus commented Sep 1, 2015

I don't think this is workable yet on iOS @brunoabinader. While I don't see a hard lag between native view draw location and GL frames, there still is some sort of out-of-sync-ness as the user dot "floats" a bit despite not changing actual geo location during animated pans.

I just don't think that it is possible to have a satisfactory experience without this sort of flow:

  1. GL frame draw.
  2. Sync native view location to same TransformState as frame draw.
  3. Update TransformState.

This is why in master we currently updateUserLocationAnnotationView() between renderSync() and nudgeTransitions() (and is why nudgeTransitions() exists separately).

Backstory: #1813

Last regression: #1904

@incanus incanus added the ⚠️ DO NOT MERGE Work in progress, proof of concept, or on hold label Sep 1, 2015
@jfirebaugh
Copy link
Contributor

Yeah, +1 to what @incanus said. This change has the effect of changing the sequence to:

  1. GL frame draw
  2. Update TransformState (via renderSyncupdate(Update::Nothing)updateTransitions)
  3. Sync native view location to different TransformState as frame draw

This will result in desynced native views.

It's possible that the following sequence would work:

  1. Update TransformState
  2. GL frame draw
  3. Sync native view location to same TransformState as frame draw

This order makes more intuitive sense than updating TransformState post-draw. There was some reason we didn't do it this way to begin with, but I can't remember what it was. If you can make it work, I'm 👍.

@brunoabinader brunoabinader force-pushed the 2207-strict_render_step_to_map_rendersync branch from 5c81c4a to 981de40 Compare September 1, 2015 21:04
@incanus
Copy link
Contributor

incanus commented Sep 1, 2015

I am still seeing stuttering render problems and an extremely jittery user dot as of 981de40. The panning is rock solid now, but pinch-zooming with inertia ("pinch fling") causes the user dot to jitter a ton.

anigif-1441142225

The best way to replicate this class of problems is to use the Xcode simulated city locations, since they don't have any GPS variance and are hardcoded single geo points.

anigif-1441142388

This applies to device as well, so be sure to run on device from Xcode once without geo simulation if you want your original location and timezone back! 😉

@1ec5
Copy link
Contributor

1ec5 commented Sep 1, 2015

I’m seeing this jitter without inertial zooming – just plain zooming. It also appears to be jittering by a fixed amount, so there’s no perceptible jitter at say z14.

@incanus
Copy link
Contributor

incanus commented Sep 1, 2015

Confirmed the jitter is in master (ticketed at #2230).

I am otherwise 👍 here @brunoabinader as of 981de40 pending tests.

I don't yet fully understand, but it sounds like the gist is that we swap the TransformState update and the renderSync per #2207 (comment), correct?

Nice work!

@friedbunny
Copy link
Contributor

You missed the opportunity to say "jitter bug" here, @incanus.

@brunoabinader
Copy link
Member Author

I don't yet fully understand, but it sounds like the gist is that we swap the TransformState update and the renderSync per #2207 (comment), correct?

Yes :-) TransformState is updated when we run a step of TransitionFrameFn with the current clock time. After that we synchronously call for the MapContext::renderSync which will draw all the things and then finally, if an update is still required (eg. due to an ongoing transform transition, let's say a rotateBy() with 500ms duration), we call for an asynchronous update in Map thread (done in Map::update()).

@incanus
Copy link
Contributor

incanus commented Sep 1, 2015

You missed the opportunity to say "jitter bug" here

@brunoabinader brunoabinader force-pushed the 2207-strict_render_step_to_map_rendersync branch from 981de40 to 9d4d314 Compare September 2, 2015 08:47
@jfirebaugh
Copy link
Contributor

@brunoabinader node branch is merged in. Providing @incanus still has appetite for this change WRT the mobile releases this week, feel free to rebase and merge.

@brunoabinader brunoabinader force-pushed the 2207-strict_render_step_to_map_rendersync branch from 9d4d314 to 0ff7cf2 Compare September 2, 2015 20:25
@mourner mourner removed the ready label Sep 2, 2015
@brunoabinader brunoabinader deleted the 2207-strict_render_step_to_map_rendersync branch September 2, 2015 20:26
@1ec5 1ec5 removed the ⚠️ DO NOT MERGE Work in progress, proof of concept, or on hold label Nov 9, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Android Mapbox Maps SDK for Android iOS Mapbox Maps SDK for iOS macOS Mapbox Maps SDK for macOS performance Speed, stability, CPU usage, memory usage, or power usage refactor
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants