Performance issues with vtkOpenGLBatchedPolyDataMapper

Hi there,

We are upgrading to vtk 9.4.2 and are experiencing slow performance. The part of our system in question has a single mapper that is associated with many actors. The problem is that the VBOs are getting constantly rebuilt. I think I have tracked the problem down to this block of code in vtkOpenGLBatchedPolyDataMapper

bool vtkOpenGLBatchedPolyDataMapper::GetNeedToRebuildBufferObjects(vtkRenderer*, vtkActor* actor)
{
  // Same as vtkOpenGLPolyDataMapper::GetNeedToRebuildBufferObjects(), but
  // we need to check all inputs, not just this->CurrentInput
  this->TempState.Clear();
  this->TempState.Append(actor->GetProperty()->GetMTime(), "actor mtime");
  for (const auto& iter : this->VTKPolyDataToGLBatchElement)
  {
    auto polydata = iter.second->Parent.PolyData;
    this->TempState.Append(polydata ? polydata->GetMTime() : 0, "input mtime");
  }
  this->TempState.Append(
    actor->GetTexture() ? actor->GetTexture()->GetMTime() : 0, "texture mtime");

  if (this->VBOBuildState != this->TempState || this->VBOBuildTime < this->GetMTime())
  {
    return true;
  }

  return false;
}


Since this gets called for multiple actors, and the actors presumably have different mtimes, the TempState never matches and so it constantly rebuilds the VBO

Ultimately we want to port this part of the system to use glyphing, but that hasn't happened yet. Is this a bug in the mapper, or should I be doing this a different way?

I should point out that we are arriving at this mapper via the delegator in vtkCompositePolyDataMapper.

there appears to be a similar problem in vtkOpenGLPolyDataMapper. Should these state checks be actor-specific?

The typical pattern in VTK is to have one mapper work with one actor, at least in my experience.

@jaswantp is the one mapper to multiple actors pattern familiar to you? If so, is there an possible modification here to avoid rebuilding VBOs?

is the one mapper to multiple actors pattern familiar to you? If so, is there an possible modification here to avoid rebuilding VBOs?

Yes. I believe the actor pointer, VBO pair can be cached internally to prevent rebuilds?

That gets complicated when you think about how to clear that cache for an actor that’s no longer used.

The only time this pattern has benefits is when you want to draw same mesh with different representations, or when you want to assign each actor/vtkProperty a different setting.

If you’re assigning different transform matrices/colors to each of the actors, I suggest using the glyph mapper instead.

yes I guess we need to bite the bullet and figure out the glyphing. In the past we have been blocked doing this as we have custom shaders. The custom shaders were not getting the right values for the specific glyph. I’d have to go back to see exactly what the problem was, but I think that’s what stopped us in the past.

Perhaps this limitation should be enforced somewhere in vtk - one actor per mapper.

Let us know if you rediscover that problem. The glyph mapper could be improved to handle custom shader code.

Perhaps this limitation should be enforced somewhere in vtk - one actor per mapper.

That’s fine by me.