Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - awr

Pages: [1]
1
Window / Re: Significant memory leak in SFML when creating multiple windows
« on: November 17, 2013, 03:22:23 am »
To put the final nail in the coffin, even this minimal code sample will cause memory usage to constantly rise:
#include <windows.h>
#include <GL/gl.h>

int main() {
        auto window = CreateWindowA( "STATIC", "", WS_POPUP | WS_DISABLED, 0, 0, 1, 1, NULL, NULL, GetModuleHandle( NULL ), NULL );
        ShowWindow( window, SW_HIDE );
        auto deviceContext = GetDC( window );

        PIXELFORMATDESCRIPTOR descriptor;
        ZeroMemory( &descriptor, sizeof( descriptor ) );
        descriptor.nSize        = sizeof( descriptor );
        descriptor.nVersion     = 1;
        descriptor.iLayerType   = PFD_MAIN_PLANE;
        descriptor.dwFlags      = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
        descriptor.iPixelType   = PFD_TYPE_RGBA;
        descriptor.cColorBits   = 32;
        descriptor.cDepthBits   = 24;
        descriptor.cStencilBits = 8;
        descriptor.cAlphaBits   = 0;

        auto format = ChoosePixelFormat( deviceContext, &descriptor );
        SetPixelFormat( deviceContext, format, &descriptor );

        while( true ) {
                auto context = wglCreateContext( deviceContext );

                wglDeleteContext( context );
        }

        ReleaseDC( window, deviceContext );
        DestroyWindow( window );
}
Since the loop only makes calls to wgl, it is wgl or the driver that is causing the leak for sure.

I tried this code sample on my home machine and like the previous, it didn't leak. Very concerning that it is a driver issue - almost certainly means that I'll have to use a different approach. Thanks for your help in shedding light on the culprit.

2
Window / Re: Significant memory leak in SFML when creating multiple windows
« on: November 16, 2013, 01:07:22 pm »
Semantics aside (I'll take your post at face value that you didn't imply my usage scenario was insane), I tried it on my home machine and I couldn't reproduce the memory leak, so it does seem to be a graphics driver issue.

3
Window / Re: Significant memory leak in SFML when creating multiple windows
« on: November 16, 2013, 11:58:07 am »
binary1248 looks for other applications that rely on opening and closing windows (creating and destroying DCs often) to provide functionality...
binary1248 finds nothing...
binary1248 considers running to the wgl/driver support people to ask if this is normal...
wgl/driver support people ignore help request upon reading problem description...
binary1248 assumes there is no demand for support of such a use case, thereby obviating effort to fix it...

This is an operating system/driver issue. I'm sure merely creating a single device context already leaks some unnoticeable amount of memory, it's just that it is so little, and it is typically a one time operation that it isn't even considered as a leak (we know how people tend to bend definitions in their favour). As long as there isn't a AAA developer behind some complaint you can keep hoping that this will get fixed one day. Or you could just resort to typical use scenarios and avoid pushing the driver beyond what any "sane" developer would even consider doing.
Such presumptuous smugness us at best unhelpful and at worst detrimental. Your inability to think up a scenario where multiple windows are created isn't indicative of an insane scenario.

FYI, I'm not creating windows for the fun of it. SFML is being used inside a windows forms control with the window actually a picturebox in the form (instantiated by passing the handle). The form is a video player control, with SFML responsible for the video rendering. Its used inside a wider application where users can view videos, in which case the an instance of the video player is created and a new window alongside it. The video playback is a periphery feature and thus the control is disposed after playback. The control can also be used an activex component in IE and on each refresh an instance is created.

Pray tell, with your no doubt boundless understanding of programming and programming techniques, how the above constitutes an insane use case, or even a particularly unorthodox one? With your use of useless rhetoric like AAA developer you are no doubt a bastion of knowledge.

4
Window / Re: Significant memory leak in SFML when creating multiple windows
« on: November 16, 2013, 03:48:48 am »
There are many different values of memory use in Windows and you are using the wrong one. The current working set is not the same as allocated memory.
Windows only gives an application a dynamically changing allowance of pages, that depends on recently used memory pages, and removes the rest from the working set to put them into some global cache, where they are technically still in memory, but are premarked to be swapped out if memory is needed later and may produce a page fault already which swaps a page back into the working set.
From memory, private bytes was increasing at the same rate as working set.

5
Window / Re: Significant memory leak in SFML when creating multiple windows
« on: November 16, 2013, 03:45:12 am »
With that being said, is your graphics driver up to date?
I upgraded a month or so ago so its quite a recent problem. I haven't tested it on another machine but I don't think it's the driver.

6
Window / Re: Significant memory leak in SFML when creating multiple windows
« on: November 15, 2013, 01:01:07 am »
Strangely enough, running memory profile tools haven't detected a memory leak, but memory is definitely increasing and not dropping.

I ran the C++ test, with both sleep statements at 500ms, for 2 minutes.

Initially, memory (working set) was at 136MB. After 2 minutes, it had increased to 593MB. The texture size was 1200x600, or 2.74MB per second. The memory was increasing at a rate of 3.8MB per second.

Running the exact same test, except with the window.draw(sprite) line commented out, resulted in working set staying constant at about 42MB.

Hopefully the following code sample will hint at the issue:

int _tmain(int argc, _TCHAR* argv[])
{
        sf::RenderWindow window;

        while (true)
        {
                window.create(sf::VideoMode(600, 300), "SFML works! ");
                sf::Texture texture;           
                texture.create(1200, 600);
                sf::Sprite sprite(texture);
                window.draw(sprite);
                window.display();

                Sleep(500);

                sf::Texture smallTexture;
                smallTexture.create(1,1);
                sf::Sprite smallSprite(smallTexture);  

                window.clear();
                window.draw(smallSprite);
                window.display();
                window.close();

                Sleep(500);
        }
}

This code produces no noticeable leak, given that the texture is so small.

However, what seems to be happening is that the memory allocated to the last texture drawn to the window is not being released for whatever reason. This hack would work for my purposes as nobody's going to notice such a small leak but it's an ugly hack regardless.

7
Window / Re: Significant memory leak in SFML when creating multiple windows
« on: November 14, 2013, 03:39:08 pm »
Too bad now my post on the deleted topic is gone. :-\

You should run an actual memory leak detection tool instead of guess from far with various tools. I highly doubt that you get leaks up to 7 MB for a 10 MB texture, it probably rather looks like "leaked".

I guess it's yet another context creation thingy, but can't be sure. That the garbage collector can't clean everything sounds reasonable given that SFML is not managed.

To add to this, it's not the process of creating the texture that's leaking, I only see a leak when deleting the current window and instantiating a new one. I did run debugdiag and I do recall seeing leaks in ig7cd32.dll though at that point there was another (context related) leak in my code that I've since removed and isn't an issue in these minimal examples. I'll re-run debugdiag or some other unmanaged leak tool tomorrow to see if I can nail where the leak is coming from.

Also, from memory when I just create the texture and sprite but don't call window.draw(...), the leak didn't occur.

8
Window / Re: Significant memory leak in SFML when creating multiple windows
« on: November 14, 2013, 03:12:21 pm »
There is no difference. It's just that I had multiple instances of Visual Studio open and I was looking at the wrong task name.  :-[ Upon running the test again as a sanity check I noticed that it in fact was also leaking.

9
Window / Significant memory leak in SFML when creating multiple windows
« on: November 14, 2013, 03:05:38 pm »
I'm using SFML in a scenario where I need to spawn multiple windows (never simultaneously). SFML is being used inside a video player control inside a wider application and whenever a user goes to play a video, a new SFML window is created.

However, this seems to create a memory leak and I suspect it might be related to opengl contexts being created. I've attached both a C# and C++ version to demonstrate the issue.

private RenderWindow SFMLWindow = null;
private void RenderLoop()
        {
            //SFMLWindow = new RenderWindow(new VideoMode(400, 300), "SFML doesn't work(s)");    
 
            while(true)
            {
                SFMLWindow = new RenderWindow(new VideoMode(800, 600), "hello");
                SFML.Graphics.Texture texture = new Texture(1920, 1080);
                SFML.Graphics.Sprite sprite = new Sprite(texture);
                SFMLWindow.Draw(sprite);
                SFMLWindow.Display();
                SFMLWindow.Clear();

                System.Threading.Thread.Sleep(1000);

                SFMLWindow.Close();
                SFMLWindow.Dispose();

                System.Threading.Thread.Sleep(1000);

                texture.Dispose();
                sprite.Dispose();
            }
     }
 


int _tmain(int argc, _TCHAR* argv[])
{
        sf::RenderWindow window;

        while (true)
        {
                window.create(sf::VideoMode(800, 600), "leak");
                sf::Texture texture;           
                texture.create(1920, 1080);
                sf::Sprite sprite(texture);
                window.draw(sprite);
                window.display();
               
                Sleep(1000);

                window.clear();
                window.close();

                Sleep(1000);
        }
}
 

10
It's not that I expected it to be fast - it's just that it seemed unreasonably slow. And indeed it was - as I highlighted in my second post, installing the latest driver resulted in a 4x improvement.

Picturebox and the entirety of Winforms uses GDI. I don't believe it uses the hardware at all. I haven't done a objective measure since but I believe with the updated graphics driver SFML renders quicker than native Winforms even on the old, crappy laptop.

11
An update - looking closer into the issue, it turns out I had a 2 year old graphics driver on the laptop. Whats more, it looks like it was a generic Intel HD driver, not one for the 3000. I updated the driver and lo and behold, the output went up from 750 textures in 20 seconds to 3000 - a 4x improvement just by updating to the latest driver.   ;D

Certainly far more in line with what'd I'd expect. That'd allow ~150 textures to be uploaded per second - as its for a video player where I'd be uploading at most 30 textures a second, it should provide ample time to decode and resize each frame.

12
Hi,

I was running a test on two of my machines with the following specs:

Machine 1 (laptop - set to Maximum Performance):
Intel I5-2520M @ 2.50GHz
4GB ram
Intel HD graphics 3000 @ 650MHz
Windows 7
750

Machine 2 (desktop):
Intel i5-760 @ 2.7GHz
Nvidia GTX 260
4GB ram
12000

Machine 3 (desktop):
Intel I5-3350P @ 3.1GHz
6GB ram
NVIDIA GeForce GT 730M
Windows 8
48000

The test was:
Load an image (1200x600) from disk into an sf::Image.
then, in a while loop:
 On every iteration, create an sf::texture from the image
Repeat as fast as possible.

I ran each test for 20 seconds and the results were:
Machine 1: 750 iterations
Machine 2: 12000 iterations
Machine 3: 48000 iterations

Note that I'm not actually drawing anything to the screen. Drawing to the screen didn't have an impact on machine 1's performance, while it reduced machine 2 to 8000 and machine 3's down to about 15000.

Each image is 2.74MB. So essentially, machine 1 was only able to transfer 100MB per second from the CPU to the GPU (or an average of 37.5 textures per second - or 27 ms per texture), whereas machine 3 was transferring 6.5GB per second (2400 textures per second - < 1ms per texture ).

That seems ridiculously slow for the Intel HD Graphics. I was expecting some slow down on the laptop but not so dramatic a difference. Is there anything that could be contributing to this? It just seems ridiculously slow for a circa 2011 machine - I get better performance using .NET and picture boxes to do the rendering.

13
DotNet / Re: Can't resize the view
« on: October 10, 2013, 07:55:34 am »
Hi Laurent,

That did it. I had just implemented a hack where I close and re instantiate the window after every resize but this does the job.

Any reason why DispatchEvents() needs to be called manually?

ALSO, just while you're here and on an unrelated matter, is it possible to add the following constructor to the .NET bindings:
            public unsafe Image(uint width, uint height, byte* pixels) :
                base(IntPtr.Zero)
            {
                SetThis(sfImage_createFromPixels(width, height, pixels));
            }

This allows you to directly pass an unmanaged pointer from C# to SFML, which is what the Image(uint width, uint height, byte[]) constructor does internally.

My usage is for a video player and we're currently using FFMPEG via our unmanaged C++ libraries to do the image decoding. We then get that as an IntPtr in our managed C# application and I'd like to pass that IntPtr directly to SFML.Net. Otherwise, I've got to do a Marshal copy into a managed C# byte array which not only adds extra overhead, it also means the garbage collector will be a lot more active. I've rebuilt the SFML .Net dlls with the above constructor and it works without issue so it'll be helpful if it can be added into the main codebase.

14
DotNet / Re: Can't resize the view
« on: October 10, 2013, 06:32:40 am »
OK, so as a sanity check, I decided to try it in C++ to see if that works properly. My C++ code:

#include "stdafx.h"
#include <SFML\Graphics.hpp>
#include <string>

int _tmain(int argc, _TCHAR* argv[])
{
        sf::RenderWindow window(sf::VideoMode(600, 300), "SFML works!");
        sf::Texture texture;
        std::string path = "INSERT PATH TO IMAGE HERE";
        texture.loadFromFile(path + "testimage.bmp");
        texture.setSmooth(true);
        sf::Sprite overlay(texture);       
        sf::View view(sf::FloatRect(0, 0, texture.getSize().x, texture.getSize().y));
        float textScale = (float) texture.getSize().x / texture.getSize().y;
        overlay.setPosition(view.getCenter().x - texture.getSize().x / 2, view.getCenter().y - texture.getSize().y / 2);
        window.setView(view);    
    while (window.isOpen())
    {          
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
        }
                float scale = (float) window.getSize().x / window.getSize().y;

                if (scale > textScale)
                {
               
                        view.setSize(texture.getSize().x * scale / textScale, texture.getSize().y);
                        view.setCenter(view.getSize().x / 2 , view.getSize().y / 2);
                        overlay.setPosition(view.getCenter().x - texture.getSize().x / 2, view.getCenter().y - texture.getSize().y / 2);
                        window.setView(view);
                }
                else if (scale < textScale)
                {
                        view.setSize(texture.getSize().x, texture.getSize().y / scale * textScale);
                        view.setCenter(view.getSize().x / 2, view.getSize().y / 2);
                        overlay.setPosition(view.getCenter().x - texture.getSize().x / 2, view.getCenter().y - texture.getSize().y / 2);
                        window.setView(view);
                }
                printf("%f\n", scale);
        window.clear();
                window.draw(overlay);
        window.display();
    }
        return 0;
}
 

And the equivalent code in C#:
        private void RenderLoop()
        {
            SFMLWindow = new RenderWindow(new VideoMode(600, 300), "SFML doesn't work(s)");
            Texture texture = new Texture("testimage.bmp");
            texture.Smooth = true;
            Sprite overlay = new Sprite(texture);
            SFML.Graphics.View view = new SFML.Graphics.View(new FloatRect(0, 0, texture.Size.X, texture.Size.Y));
            float textScale = (float)texture.Size.X / texture.Size.Y;
            overlay.Position = new Vector2f(view.Center.X - texture.Size.X / 2, view.Center.Y - texture.Size.Y / 2);
            SFMLWindow.SetView(view);

            while (SFMLWindow.IsOpen() && FormOpen)
            {
                Application.DoEvents();
                float scale = (float)SFMLWindow.Size.X / SFMLWindow.Size.Y;

                if (scale >= textScale)
                {
                    view.Size = new Vector2f(texture.Size.X * scale / textScale, texture.Size.Y);
                    view.Center = new Vector2f(view.Size.X / 2, view.Size.Y / 2);
                    overlay.Position = new Vector2f(view.Center.X - texture.Size.X / 2, view.Center.Y - texture.Size.Y / 2);
                    SFMLWindow.SetView(view);
                }
                else if (scale < textScale)
                {
                    view.Size = new Vector2f(texture.Size.X, texture.Size.Y / scale * textScale);
                    view.Center = new Vector2f(view.Size.X / 2, view.Size.Y / 2);
                    overlay.Position = new Vector2f(view.Center.X - texture.Size.X / 2, view.Center.Y - texture.Size.Y / 2);
                    SFMLWindow.SetView(view);
                }

                SFMLWindow.SetView(view);
                SFMLWindow.Clear();
                SFMLWindow.Draw(overlay);
                SFMLWindow.Display();
                break;
            }
        }

And the differences in output:
C++ (exactly as I expected it to be):


C# (nothing like I expected it to be):


As you can see, the C++ implementation resizes, keeps proportions in check and adds black bars on top/bottom or on sides depending on the window ratio. Clearly, this isn't working at all in C#.

One thing that I find interesting is that when I log the SFMLWindow's properties, its size, position and view never change. I am using the 2.1 bindings.

15
DotNet / Can't resize the view
« on: October 10, 2013, 02:34:29 am »
Hi all,

I'm having trouble getting the view to work correctly in SFML.Net. It seems that it should be relatively straight forward but no matter what I try, I can't get it work properly.

What I want is:http://www.sfml-dev.org/forums/Themes/ds-natural_20/images/bbc/pre.gif
Embed the render window in a .NET picturebox (this works fine)
Display an image that takes up the entirety of the picture box (this also works fine initially) and is centred in the image box
Upon resizing the picturebox (or form), have the image resize with it. I managed to get this to work when shrinking the picture box, but it doesn't work correctly when making it larger (the view area doesn't change).

My code is (this doesn't work but I don't see what's wrong with it):
// initialise SFML:
        private void pictureBox2_Click(object sender, EventArgs e)
        {
            if (SFMLWindow != null)
                return;
            pictureBox2.Show();
            SFMLWindow = new RenderWindow(pictureBox2.Handle);

            view = new SFML.Graphics.View(new FloatRect(0, 0, this.ClientSize.Width, this.ClientSize.Height));
            SFMLWindow.SetView(view);
            RenderLoop();
        }

private void RenderLoop()
        {            
            SFML.Graphics.Image image3 = new SFML.Graphics.Image("testimage.bmp");                          
            int i = 0;
           
            while (FormOpen)
            {
             
                view = new SFML.Graphics.View(new Vector2f(pictureBox2.ClientSize.Width / 2, pictureBox2.ClientSize.Height / 2), new Vector2f(pictureBox2.ClientSize.Width, pictureBox2.ClientSize.Height));
               
               
                SFMLWindow.SetView(view);
// i intentionally create a new sprite each time round as the application is for a video player, which would need a new sprite to be made for each frame
                Sprite testsprite = new Sprite(new Texture(image3));
                testsprite.Texture.Smooth = true;

                testsprite.Scale = new Vector2f((float) this.ClientSize.Width / testsprite.Texture.Size.X, (float) this.ClientSize.Height / testsprite.Texture.Size.Y);

                Console.WriteLine(SFMLWindow.Size);

                Application.DoEvents(); // Required for the form controls to respond
                SFMLWindow.Clear(SFML.Graphics.Color.White);
                SFMLWindow.Draw(testsprite);
 
                //Do your drawing code here
                SFMLWindow.Display();              
                testsprite.Texture.Dispose();
                testsprite.Dispose();
                System.Threading.Thread.Sleep(80);
            }
        }

It doesn't work. Note that even changing the size of the window manually, using
size = new Vector2u((uint)pictureBox2.ClientSize.Width, (uint)pictureBox2.ClientSize.Height);
                SFMLWindow.Size = size;

doesn't work. When I log the size, its always the form's initial size.

Not sure what the issue is. I've used opengl before with Android and had very few issues with getting the view to do what I want. This seems like it should be quite straight forward...

Pages: [1]