开发者

Is there any reason GDI+ would be slower on a 64-bit Operating System (or maybe it's Windows 7 related)

开发者 https://www.devze.com 2023-03-22 15:25 出处:网络
Background I\'m working on an application that is supposed to work on every windows platform from XP onwards in the same manner.Through the .NET framework this has been very easy, for the most part.T

Background

I'm working on an application that is supposed to work on every windows platform from XP onwards in the same manner. Through the .NET framework this has been very easy, for the most part. The application runs across a variety of touch surfaces. The application targets .Net 3.0, but if for some reason I should move to .Net 3.5, I can do that. I am unable to use 4.0.

The application makes heavy use of GDI+ through the System.Drawing namespace. Now, I understand that GDI+ either isn't hardware accelerated at all or is only accelerated in a very small number of graphics cards, so I expect to have some performance issues. However, this issue is blaring and makes the application's usability significantly lower. I would rather not rewrite the entire application to target DirectX or OpenGL if it can be avoided with an easy fix.

The Problem

We recently inst开发者_Python百科alled Windows 7 64-bit on one of the touch tables. It was the first time the application was run on a Windows 7 64-bit machine. In any event, any drawing (specifically DrawLine) with more than one finger on the device at a time causes a ridiculous amount of lag. This lag isn't apparent on 32-bit Windows XP or 32-bit Windows 7, so I think it might be specific to 64-bit Windows 7 (I don't have a 64-bit XP machine to test with).

The application was also forced to run as a 32-bit application due to one of the .dll files only have 32-bit libraries available to compile it. I read somewhere that forcing a process into 32-bit mode on a 64-bit system could cause performance issues, but when I upgraded the SDK we were using and made a 64-bit specific .dll and application, the problem persisted.

I read on this other StackOverflow thread that there should be no differences between a 32-bit and a 64-bit application with relation to GDI+. This doesn't seem to be the case here.

So what it comes down to: Do any of you know why there might be such a huge performance difference between Windows 32-bit and Windows 64-bit? If I can't find a solution, I'll have to spend a bit of time making everything use hardware accelerated drawing. I would like to avoid that if at all possible.

Thanks everyone!

EDIT: Requested code snippet

    public delegate void drawLineDelegate(Color color, float width, int x1, int y1, int x2, int y2);
    public void drawLine(Color color, float width, int x1, int y1, int x2, int y2)
    {
        if (InvokeRequired)
        {
            Invoke(new drawLineDelegate(drawLine), new object[] { color, width, x1, y1, x2, y2 });
        }
        else
        {
            try
            {
                lock (drawLock)
                {
                    pen.Width = width;
                    pen.Color = color;
                    scaledPen.Width = width * this.Width / Canvas.Width;
                    scaledPen.Color = color;
                    Point p1 = scalePointToScreen(new Point(x1, y1));
                    Point p2 = scalePointToScreen(new Point(x2, y2));

                    graphics.DrawLine(pen, x1, y1, x2, y2);
                    scaledGraphics.DrawLine(scaledPen, p1.X, p1.Y, p2.X, p2.Y);

                    this.Invalidate(new Rectangle(Math.Min(p1.X, p2.X) - (int)scaledPen.Width, Math.Min(p1.Y, p2.Y) - (int)scaledPen.Width,
                          Math.Abs(p2.X - p1.X) + 2 * (int)scaledPen.Width, Math.Abs(p2.Y - p1.Y) + 2 * (int)scaledPen.Width));
                }
            }
            catch (Exception ex)
            {
                if (Scribbler.Properties.Settings.Default.LogLevel >= 2)
                {
                    Scribbler.ScribblerForm.WriteLogMessage(ex.ToString());
                }
            }
        }

Edit: Further Research I did some more scouring of the internet with relation to the NVidia cards we use on our machines. This lead me to several posts on the NVidia Developer Forums about people with the same issue. The common answer is that GDI is deprecated on Windows 7 and the newer NVidia graphics drivers (from 182.5 onwards) suffer from GDI performance issues. The solutions were either to update to Direct3D or use old drivers. Does anyone know for certain whether this is the best course of action?


I notice that you're locking your drawing code. Are you drawing from multiple threads? I suspect that the lock may have something to do with your performance issues.

You shouldn't draw from multiple threads unless you know EXACTLY what you are doing. There are way too many gotchas in the OS regarding multithreaded graphics use.

Because you have an Invoke in there, that is a very slow process. You don't want to be invoking all the time. You should never be calling this method from a background thread. It also seems like your lock is not really needed, because your invoke would prevent any thread access other than the message pump thread.

I think you would benefit greatly from redesigning your painting workflow to ensure it's called once, and only from the main message pump thread.

I'm also a bit confused about why you're invalidating areas within your drawing code.. that's likely to just create an infinite draw loop, which could also be part of your problem.


First of all I'm not sure you'll get a lot of performance benefits in using WPF. If you do decide to rewrite your graphics code, I suggest moving to Direct2D (you can still write the code in C#). Here's an article comparing the performance of all of the three libraries: http://www.teechart.net/reference/articles/WhitePaper_Direct2D.htm

I'm a developer of Maperitive, which heavily uses GDI+ to render maps. I cannot say that I noticed any major performance issues on 64bit Windows 7, but then again I'm not really testing it on any other system (apart from Ubuntu's Mono on a netbook, which is understandably a lot slower).

I guess it would be easier to discuss this if you showed us some snippets of your line drawing code. On the other hand the problem could be hardware related (graphics card driver?). How many different Win 7 64bit configurations have you tested this on?

UPDATE:

About "deprecated" GDI on Windows 7: I very much doubt that would be true because you would then notice performance problems not only on your application and I doubt Microsoft would be bold enough to do something like this for backward compatibility reasons. Do you have any links that prove this claim?

About your code: you haven't shown all of it and its real purpose, but from the context I suspect you use the Graphics object created using Control.CreateGraphics() method (and you call the line drawing from other threads too, which can be a performance issue in itself). I suspect you do this to draw lines interactively (instead of redrawing everything through OnPaint() method). In general this practice is problematic (here's Bob Powell's explanation).

BTW what is the difference between graphics and scaledGraphics?

If you could explain what exactly you are trying to achieve through this method, maybe we can find a better (faster) way to do this.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号