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

DirtyFlag optimization by avoiding remaking decision #379

Open
nategoose opened this issue Oct 11, 2023 · 0 comments
Open

DirtyFlag optimization by avoiding remaking decision #379

nategoose opened this issue Oct 11, 2023 · 0 comments

Comments

@nategoose
Copy link

Once you know that a sub-tree is dirty, you know that all of its children are dirty and can avoid making that decision again.
Splitting render into Clean (so far) and (known to be) Dirty functions lets most of the nodes only have to either make the decision about clean/dirty (on the clean so far path) or combine the transforms (on the dirty path). The only node that has to do both is the 1st node reached that is dirty.
Note that if renderMesh can be moved to the end of the calls (after rendering children) then tail call optimization is also a possibility. Tail call optimization is not reasonably doable when the functions end in a for loop. But it's also possible that renderMesh might be more expensive if done after children.

diff --git a/code/cpp/dirty-flag.h b/code/cpp/dirty-flag.h
index 31df713..cf674df 100644
--- a/code/cpp/dirty-flag.h
+++ b/code/cpp/dirty-flag.h
@@ -147,6 +147,8 @@ namespace DirtyFlag
       static const int MAX_CHILDREN = 16;
       GraphNode* children_[MAX_CHILDREN];
       int numChildren_;

  •      void renderDirty(Transform parentWorld);
  •      void renderClean();
           //^omit
         };
         //^dirty-graph-node
    @@ -162,18 +164,36 @@ namespace DirtyFlag
         //^dirty-render
         void GraphNode::render(Transform parentWorld, bool dirty)
         {
  •      dirty |= dirty_;
           if (dirty)
           {
  •        world_ = local_.combine(parentWorld);
  •        dirty_ = false;
  •        renderDirty(parentWorld);
  •      } else
  •      {
  •        renderClean();
           }
  •    }
  •    void GraphNode::renderDirty(Transform parentWorld)
  •    {
  •      world_ = local_.combine(parentWorld);
  •      dirty_ = false;
           if (mesh_) renderMesh(mesh_, world_);

       for (int i = 0; i < numChildren_; i++)
       {

  •        children_[i]->render(world_, dirty);
  •        children_[i]->renderDirty(world_);
  •      }
  •    }
  •    void GraphNode::renderClean()
  •    {
  •      if (dirty_)
  •      {
  •        renderDirty(world_);
  •      } else
  •      {
  •        if (mesh_) renderMesh(mesh_, world_);
  •        for (int i = 0; i < numChildren_; i++)
  •        {
  •          children_[i]->renderClean();
  •        }
           }
         }
         //^dirty-render
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

No branches or pull requests

1 participant