COW and RNA #56172

Closed
opened 2018-07-31 13:52:09 +02:00 by Bastien Montagne · 7 comments

Currently RNA only has access to original data, never evaluated one. We have some RNA functions (mainly accessors) that need runtime-only data (generated by depsgraph into COW IDs), like e.g. the bounding box for object.dimension.

Currently, this is broken, usually dimensions just get outdated (see #55769), but this can also lead to a crash with curves in some cases, when trying to compute bbox from runtime.curve_cache (see #56064) e.g.

I can think of several ways to address the problem:

Pass bContext to getters/setters RNA functions (as we already do e.g. with update callbacks, dynamic enum generators, etc.).

This would imply adding a new getters/setters func pointers in RNA (with extended signature) I guess, with e.g. a flag to indicate that that property needs bContext in its accessors. This would also imply some sort of mechanism to set 'active' context in RNA (using a static pointer maybe?), which would need to be set before accessing any of those 'context' properties.
*** Python binding could do that easily, but may require some annoying adjustments to CPP code?

Give access to active depsgraph.

E.g. storing depsgraph in a static pointer when calling DEG_make_active(), and adding a DEG_get_active() callback? That would still give wrong data (and potentially nasty crash/corruption?) in case one is working with data from non-active depsgraph.
*** Thinking about render engines especially here, since those get data from a specific depsgraph - though since they do not access original data at all, maybe that would still be perfectly fine?

  • Forbid any eval-dependent data access in depsgraph (i.e. not more object.dimensions e.g.).
  • Make all eval-dependent data access through functions instead of properties.
    That would make dimension non-editable! That would change a lot UI too…

Copy back things like object bbox from evaluated to orig datablocks (i.e. extend what we already do with a few things like object transform data iirc).

Tried that btw, does not work in many cases (e.g. with curves), since their bboxes are not computed during evaluation... We could enforce computing bboxes at that step, but meh… really not an elegant solution.

Solution 1. is probably doable, but most likely a PITA, with lots of code to edit, and potential side effects.

I have a rather strong preference for 2. now, would be by far the simplest/nicest solution imho. Not sure at all that would be fine and sane regarding DEG design though? :/ Also not clear in my mind currently, whether we have one active depsgraph for whole Blender, or one per window?

Other solutions I do not really like currently…

Currently RNA only has access to original data, never evaluated one. We have some RNA functions (mainly accessors) that need runtime-only data (generated by depsgraph into COW IDs), like e.g. the bounding box for `object.dimension`. Currently, this is broken, usually dimensions just get outdated (see #55769), but this can also lead to a crash with curves in some cases, when trying to compute bbox from runtime.curve_cache (see #56064) e.g. I can think of several ways to address the problem: # Pass bContext to getters/setters RNA functions (as we already do e.g. with update callbacks, dynamic enum generators, etc.). **This would imply adding a new getters/setters func pointers in RNA (with extended signature) I guess, with e.g. a flag to indicate that that property needs bContext in its accessors.** This would also imply some sort of mechanism to set 'active' context in RNA (using a static pointer maybe?), which would need to be set before accessing any of those 'context' properties. *** Python binding could do that easily, but may require some annoying adjustments to CPP code? # Give access to active depsgraph. **E.g. storing depsgraph in a static pointer when calling `DEG_make_active()`, and adding a `DEG_get_active()` callback?** That would still give wrong data (and potentially nasty crash/corruption?) in case one is working with data from non-active depsgraph. *** Thinking about render engines especially here, since those get data from a specific depsgraph - though since they do not access original data at all, maybe that would still be perfectly fine? - Forbid any eval-dependent data access in depsgraph (i.e. not more object.dimensions e.g.). - Make all eval-dependent data access through functions instead of properties. **That would make dimension non-editable!** That would change a lot UI too… # Copy back things like object bbox from evaluated to orig datablocks (i.e. extend what we already do with a few things like object transform data iirc). **Tried that btw, does not work in many cases (e.g. with curves), since their bboxes are not computed during evaluation...** We could enforce computing bboxes at that step, but meh… really not an elegant solution. Solution 1. is probably doable, but most likely a PITA, with lots of code to edit, and potential side effects. I have a rather strong preference for 2. now, would be by far the simplest/nicest solution imho. Not sure at all that would be fine and sane regarding DEG design though? :/ Also not clear in my mind currently, whether we have one active depsgraph for whole Blender, or one per window? Other solutions I do not really like currently…
Bastien Montagne self-assigned this 2018-07-31 13:52:09 +02:00
Author
Owner

Added subscribers: @mont29, @Sergey, @ideasman42, @brecht

Added subscribers: @mont29, @Sergey, @ideasman42, @brecht
Author
Owner

Spent some time yesterday checking on that problem again, and updated/refined my analysis…

We really need to do something (will fix crash itself now, but that won’t be an actual problem solution at all!)

Spent some time yesterday checking on that problem again, and updated/refined my analysis… We really need to do something (will fix crash itself now, but that won’t be an actual problem solution at all!)

There was a decision to have only one active depsgraph for editing purposes, all the other depsgraphs are for viewing / rendering. So that should help solve this problem?

We are already flushing back object matrices to the original, and I think we can do the same for dimensions. So I think we should go with 5). It's not clear to me why bounding box computation not happening during evaluation would be a problem. We can make it happen during evaluation in that case, which is better for multithreading anyway. If for some reason that doesn't work it should be possible to wrap the code in such a way that the flushing still happens when the bounding box is computed.

Option 1) seems like it would make the API less predictable to use, 2) makes writing scripts harder, 3) 4) are not good because we need editable dimensions.

There was a decision to have only one active depsgraph for editing purposes, all the other depsgraphs are for viewing / rendering. So that should help solve this problem? We are already flushing back object matrices to the original, and I think we can do the same for dimensions. So I think we should go with 5). It's not clear to me why bounding box computation not happening during evaluation would be a problem. We can make it happen during evaluation in that case, which is better for multithreading anyway. If for some reason that doesn't work it should be possible to wrap the code in such a way that the flushing still happens when the bounding box is computed. Option 1) seems like it would make the API less predictable to use, 2) makes writing scripts harder, 3) 4) are not good because we need editable dimensions.
Author
Owner

@brecht Solution 2) does not involve modifying scripts, it’s RNA accessors that need to be updated (getting active depsgraph and calling relevant functions with relevant evaluated data). See a quick-slap test in P794 (seems to be working, but we’d need @Sergey to know whether that is 'allowed' or not I guess ;) ).

I’d go to solution 5) only if we cannot make 2) to work (since it’s much less generic, and involves extra processing that may not be needed in most cases).

@brecht Solution 2) does not involve modifying scripts, it’s RNA accessors that need to be updated (getting active depsgraph and calling relevant functions with relevant evaluated data). See a quick-slap test in [P794](https://archive.blender.org/developer/P794.txt) (seems to be working, but we’d need @Sergey to know whether that is 'allowed' or not I guess ;) ). I’d go to solution 5) only if we cannot make 2) to work (since it’s much less generic, and involves extra processing that may not be needed in most cases).

But we already do 5) for object matrices. To me it seems best to have a single consistent solution, what breaks if we just copy back the boundbox to the original here?

void BKE_object_eval_done(Depsgraph *depsgraph, Object *ob)
{
    ...
    if (DEG_is_active(depsgraph)) {
        Object *ob_orig = DEG_get_original_object(ob);
        copy_m4_m4(ob_orig->obmat, ob->obmat);
        ...
    }
}

Meshes, curves and metaballs already compute the bounding box on the evaluated object as far as I can tell.

But we already do 5) for object matrices. To me it seems best to have a single consistent solution, what breaks if we just copy back the boundbox to the original here? ``` void BKE_object_eval_done(Depsgraph *depsgraph, Object *ob) { ... if (DEG_is_active(depsgraph)) { Object *ob_orig = DEG_get_original_object(ob); copy_m4_m4(ob_orig->obmat, ob->obmat); ... } } ``` Meshes, curves and metaballs already compute the bounding box on the evaluated object as far as I can tell.

This issue was referenced by e66084268c

This issue was referenced by e66084268ccc08bfde4b384211f5a248a805036d
Author
Owner

Changed status from 'Open' to: 'Resolved'

Changed status from 'Open' to: 'Resolved'
Sign in to join this conversation.
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
3 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#56172
No description provided.