Eto.Drawable drawing speed issue

Hi All,

we are creating a panel with an Eto.Drawable but whenever I have to draw a decent amount of lines the drawing is really slow. Did anyone tried to do something similar? Do you have a tip for drawing things faster?

Thanks a lot,
Alberto

I guess because Eto isn’t hardware-acclerated?

So the suggetion is use another framework?

Eto is a wrapper and on Windows it’s targeting WPF. WPF uses DirectX and this is definitely hardware-accelerated. The problem with Eto is its whole concept of being a niche wrapper, with the lack of proper documentation and profiling tools. You could try to implement it directly in WPF, using Visual Studio Profiling Tools to find out what is causing the Render issues. But unless you have already worked with WPF, the learning curve is steep. The issue you are describing could be anything. If you need high performance you can also directly create a OpenGL/Vulkan or DirectX window. But this also comes with disadvantages, such as having no UI controls by default… Usually bad performance is not a subject of the framework these days, but very likely a programming mistake, such as overloading the UI thread, Inefficent Resource management (e.g. creating a pen for every line) or 1000 other things…

Could you provide an example of what your drawing code looks like?

Of course, the method is pretty simple. It is drawing a series of lines that represent the UV map of the given mesh. This code already uses a graphics path that is stored and presented when it is needed. The original version with direct line drawing is unusable when the mesh has more than 1000 tris.

    public void Draw(Graphics g)
    {

      var minpos = MinPosition;
      var maxpos = BottomRightPosition;

      using (var gstate = g.SaveTransformState()) {
        g.TranslateTransform(m_offset);
        g.ScaleTransform(m_zoomLevel);

        for (float pos = 0.1f; pos < 1.0f; pos += 0.1f) {

          g.DrawLine(LineColor, 0.0f, (pos), (1.0f), (pos));
          g.DrawLine(LineColor, (pos), (0.0f), (pos), (1.0f));
        }

        g.DrawRectangle(OutlinePen, minpos.X, minpos.Y, maxpos.X - minpos.X, maxpos.Y - minpos.Y);

        foreach (var storage in UvStorage) {
          var uvmesh = storage.Uvs;
          var mesh = storage.OriginalMesh;

          if (uvmesh.VertexCount == 0) {
            continue;
          }

          if (storage.DrawingCache == null) {

            var edgePath = new GraphicsPath();
 
            for (int i = 0; i < mesh.Faces.Count; ++i) {
              var face = mesh.Faces[i];

              edgePath.MoveTo((uvmesh.Uvs[face.A * 2 + 0]), (uvmesh.Uvs[face.A * 2 + 1]));
              edgePath.LineTo((uvmesh.Uvs[face.B * 2 + 0]), (uvmesh.Uvs[face.B * 2 + 1]));
              edgePath.LineTo((uvmesh.Uvs[face.C * 2 + 0]), (uvmesh.Uvs[face.C * 2 + 1]));

              if (face.IsTriangle) {
                edgePath.LineTo((uvmesh.Uvs[face.A * 2 + 0]), (uvmesh.Uvs[face.A * 2 + 1]));

              } else {
                edgePath.LineTo((uvmesh.Uvs[face.D * 2 + 0]), (uvmesh.Uvs[face.D * 2 + 1]));
                edgePath.LineTo((uvmesh.Uvs[face.A * 2 + 0]), (uvmesh.Uvs[face.A * 2 + 1]));
              }
            }

            storage.PointCache = pointPath;
            storage.DrawingCache = edgePath;
          }

          g.DrawPath(EdgePen, storage.DrawingCache);
        }

      }
    }

When and how often do you call the “Draw” method? Hopefully not on an input event such as the MouseWheel event? Have you tried drawing it on a canvas once and only scale the canvas? You should also freeze the path. It might also a good idea to reduce the quality by reducing anti-aliasing etc. The alternative would be drawing the uv map directly into a bitmap using a low-level implementation or uitlizing an open-gl window. C# offers some libraries such as opentk. It might also be worth trying to use the 3d drawing feature of WPF, although I’m not sure if Eto supports that. The Viewport3d of WPF utilizes DirectX much better

You might want to try calling edgePath.AddLines instead of many moveto/lineto combinations. I’m not sure if this will help, but it is worth a shot. At a lower level, drawing a big set of lines is simpler to optimize for display than many small line lists.