-
Notifications
You must be signed in to change notification settings - Fork 615
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
Various optimizations related to camera linking and mesh normals #2532
base: main
Are you sure you want to change the base?
Conversation
Modifications in two ways
The hack comments should do some changes, As follows: diff --git a/vispy/scene/cameras/base_camera.py b/vispy/scene/cameras/base_camera.py
index c59f340d..882b6bfc 100644
--- a/vispy/scene/cameras/base_camera.py
+++ b/vispy/scene/cameras/base_camera.py
@@ -62,6 +62,7 @@ class BaseCamera(Node):
# Linked cameras
self._linked_cameras = {}
self._linked_cameras_no_update = None
+ self._setting_state = False
# Variables related to transforms
self.transform = NullTransform()
@@ -356,6 +357,7 @@ class BaseCamera(Node):
"""
state = state or {}
state.update(kwargs)
+ self._setting_state = True
# In first pass, process tuple keys which select subproperties. This
# is an undocumented feature used for selective linking of camera state.
@@ -383,6 +385,8 @@ class BaseCamera(Node):
if key not in self._state_props:
raise KeyError('Not a valid camera state property %r' % key)
setattr(self, key, val)
+ self._setting_state = False
+ self.view_changed()
def link(self, camera, props=None, axis=None):
"""Link this camera with another camera of the same type
@@ +443,8 @@ class BaseCamera(Node):
def view_changed(self):
"""Called when this camera is changes its view. Also called
when its associated with a viewbox.
"""
+ if self._setting_state:
+ return
if self._resetting:
return # don't update anything while resetting (are in set_range)
diff --git a/vispy/scene/cameras/base_camera.py b/vispy/scene/cameras/base_camera.py
--- a/vispy/scene/cameras/base_camera.py
+++ b/vispy/scene/cameras/base_camera.py
@@ +377, +386 @@ class BaseCamera(Node):
for key in list(state.keys()):
if isinstance(key, tuple):
key1 = key[0]
if key1 not in state:
root_prop = getattr(self, key1)
# We make copies by passing the old object to the type's
# constructor. This needs to be supported as is the case in
# e.g. the geometry.Rect class.
state[key1] = root_prop.__class__(root_prop)
- nested_setattr(state[key1], key[1:], state[key])
+ if nested_getattr(state[key1], key[1:]) != state[key]:
+ nested_setattr(state[key1], key[1:], state[key])
# In second pass, assign the new root properties.
for key, val in state.items():
if isinstance(key, tuple):
continue
if key not in self._state_props:
raise KeyError('Not a valid camera state property %r' % key)
- setattr(self, key, val)
+ if getattr(self, key) != val:
+ setattr(self, key, val) Both of these methods seem to have similar performance; either one is fine. However, as for which one is more elegant, I'm not an expert in this. |
For 1, I wasn't sure if I liked it going it view_changed(). Did that make a difference in performance for you? I was nervous that For 2, the idea is that setting state may not be the only way people are setting these properties. It could be from the user (keyboard or user interface input) or part of some timer trigger. So even though it is more work I think it is more useful in the long run to have these checks per property. |
Most importantly I should ask, @JintaoLee-Roger do these changes make your application usable? |
Both of these two hacks satisfy my needs. |
So when you said the above, you mean that either this "debouncing" of the set state (the |
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.
Looks good to me! Didn't test it myself, but the code looks ok.
See #2530
CC @JintaoLee-Roger
This is a collection of optimizations uncovered in #2530 debugging by me or @JintaoLee-Roger. The main ideas are to not update camera properties unless the value has actually changed. This prevents expensive transform-updating methods from being called unnecessarily. This is especially noticeable when a single camera move updates 4+ properties of a linked property and each one tries to report that the view/transform has changed. It does this in two ways:
This PR also adds some checks in the mesh light filter to see if vertex normals have actually changed before submitting/uploading the normals to the GPU. It also enables the use of a previously unused (yet defined for some reason?)
MeshData._vertex_normal_indexed_by_faces
. This allows the check in the light filter to actually work with a simple identity (is
) check.TODO: