This problem is apparently due to a bug in vtk-9.0, as my application now works with vtk-9.2. Note that per advised in vtkGenericOpenGLRenderWindow documentation, my code installs a callback that asserts the window as current when MakeCurrent() is called:
// Invoke callback when renderWindow_ is made current
renderWindow_->AddObserver(vtkCommand::WindowMakeCurrentEvent,
this, &QVtkRenderer::makeCurrentCallback);
And the callback does this:
/// Assert renderWindow_ as current in response to WindowMakeCurrent event
void QVtkRenderer::makeCurrentCallback(vtkObject *, unsigned long eid,
void *callData) {
std::cout << "makeCurrentCallback()!" << std::endl;
// Assert render window as current
renderWindow_->SetIsCurrent(true);
}