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

Add some thread safety to Qgs3DMapSettings usage #58398

Merged
merged 11 commits into from
Aug 28, 2024

Conversation

nyalldawson
Copy link
Collaborator

Create a small, cheap to copy (non-qobject) class
Qgs3DMapSettingsSnapshot which is designed to store just cheap properties of Qgs3DMapSettings. Then use this object wherever possible to avoid accessing the (non-thread safe) Qgs3DMapSettings object for retrieval of simple map properties (eg crs, extent, ...)

Refs qgis/QGIS-Enhancement-Proposals#301

@github-actions github-actions bot added this to the 3.40.0 milestone Aug 15, 2024
@nyalldawson
Copy link
Collaborator Author

@wonder-sk @ptitjano @benoitdm-oslandia as previously discussed.

Copy link

github-actions bot commented Aug 15, 2024

🪟 Windows builds ready!

Windows builds of this PR are available for testing here. Debug symbols for this build are available here.

(Built from commit 64a22e1)

@nyalldawson nyalldawson force-pushed the map_settings_snapsot branch from 3326d91 to 02d5ce4 Compare August 16, 2024 01:29
@wonder-sk
Copy link
Member

@nyalldawson few questions about this:

  • what is your preference - shall we have the new "snapshot" class contain everything that may be required in 3D code responsible for creating entities just without QObject/signal stuff (kind of equivalent of QgsMapSettings for 2D rendering) or shall we have it as a subset of data (kind of equivalent of QgsRenderContext for 2D rendering) ? It looks like you were aiming for the latter, but I wanted to double check what the philosophy of the class would be (minimal vs maximal)

    • if we end up doing something equivalent to QgsRenderContext, then maybe it would be good to just extend the existing Qgs3DRenderContext class (which in fact contains Qgs3DMapSettings reference, and it has a lot of overlap with the new "snapshot" class)
  • where would be the boundary between the "snapshot" class and the full Qgs3DMapSettings qobject class would be available? Right now, I see that e.g. point cloud entity uses just the snapshot class, but vector/rule-based entity uses the full Qgs3DMapSettings qobject. It would be good to draw the line somewhere - my suggestion is that 3D entity implementations could have access to Qgs3DMapSettings, to make use of its signals if needed, but anything deeper inside the code (e.g. chunk loaders, texture generators) could only have access to snapshots. If we agree on this, then probably it would be good if Qgs3DMapSettings would be a member variable of the parent Qgs3DMapSceneEntity class. What do you think?

@nyalldawson
Copy link
Collaborator Author

@wonder-sk

Thanks for the feedback!

what is your preference - shall we have the new "snapshot" class contain everything that may be required in 3D code responsible for creating entities just without QObject/signal stuff (kind of equivalent of QgsMapSettings for 2D rendering) or shall we have it as a subset of data (kind of equivalent of QgsRenderContext for 2D rendering) ? It looks like you were aiming for the latter, but I wanted to double check what the philosophy of the class would be (minimal vs maximal)

I lean toward keeping it minimal, and adding the properties only when we have a need to do so. (None of this is exposed to Python yet, so there's no disadvantage I can see in adding properties on demand when we need them in c++ code).

if we end up doing something equivalent to QgsRenderContext, then maybe it would be good to just extend the existing Qgs3DRenderContext class (which in fact contains Qgs3DMapSettings reference, and it has a lot of overlap with the new "snapshot" class)

Makes sense to me. I'll rework this and condense the new class into Qgs3DRenderContext, and remove the Qgs3DMapSettings property from Qgs3DRenderContext.

where would be the boundary between the "snapshot" class and the full Qgs3DMapSettings qobject class would be available? Right now, I see that e.g. point cloud entity uses just the snapshot class, but vector/rule-based entity uses the full Qgs3DMapSettings qobject. It would be good to draw the line somewhere - my suggestion is that 3D entity implementations could have access to Qgs3DMapSettings, to make use of its signals if needed, but anything deeper inside the code (e.g. chunk loaders, texture generators) could only have access to snapshots. If we agree on this, then probably it would be good if Qgs3DMapSettings would be a member variable of the parent Qgs3DMapSceneEntity class. What do you think?

I was originally going for a "use the snapshot wherever we can get away with it" approach, but I like the consistency of the Qgs3DMapSceneEntity change you describe better 👍

@benoitdm-oslandia
Copy link
Contributor

@nyalldawson I was wondering if this new class must be read-only ie. without any setters. It disturbs me a bit a have an object acting as a clone of the main Qgs3DMapSettings but with updated properties. When and how do you update the main Qgs3DMapSettings object from the updated Qgs3DMapSettingsSnapshot?

Create a small, cheap to copy (non-qobject) class
Qgs3DMapSettingsSnapshot which is designed to store
just cheap properties of Qgs3DMapSettings. Then use this
object wherever possible to avoid accessing the (non-thread
safe) Qgs3DMapSettings object for retrieval of simple
map properties (eg crs, extent, ...)

Refs qgis/QGIS-Enhancement-Proposals#301
@nyalldawson nyalldawson force-pushed the map_settings_snapsot branch from c51cc93 to 240cdde Compare August 26, 2024 23:58
@nyalldawson
Copy link
Collaborator Author

@wonder-sk ok, all done as discussed

@benoitdm-oslandia

I was wondering if this new class must be read-only ie. without any setters. It disturbs me a bit a have an object acting as a clone of the main Qgs3DMapSettings but with updated properties. When and how do you update the main Qgs3DMapSettings object from the updated Qgs3DMapSettingsSnapshot?

Indeed they were only used to initially set the properties from the map settings. I've removed all the setters now, and just set the members directly when first constructing Qgs3DRenderContext

Copy link
Contributor

@benoitdm-oslandia benoitdm-oslandia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the improvements!

CMakeLists.txt Show resolved Hide resolved
src/3d/chunks/qgschunkedentity_p.cpp Outdated Show resolved Hide resolved
src/3d/qgs3drendercontext.h Show resolved Hide resolved
Copy link
Member

@wonder-sk wonder-sk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👏 well done - nice cleanup!

@qgis qgis deleted a comment from github-actions bot Aug 28, 2024
@nyalldawson
Copy link
Collaborator Author

Unrelated clang tidy failure

@nyalldawson nyalldawson merged commit ba61df7 into qgis:master Aug 28, 2024
28 of 29 checks passed
@nyalldawson nyalldawson deleted the map_settings_snapsot branch August 28, 2024 02:38
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

Successfully merging this pull request may close these issues.

3 participants