I am using glDrawPixels to display an image. I know, I should probably be using textures but there are reasons I'm not. Well at least not for now. Anyways, image being displayed is frequently being updated as if it is being scanned in. This works fine as long as I let it sit and finish the "scanning", however, if I click on the screen while the "scanning is still going on I get an AccessViolation Exception at my glDrawPixels.
Gl.glDrawPixels(mImageWidth, mImageHeight, Gl.GL_LUMINANCE, Gl.GL_UNSIGNED_SHORT, mDisplayBuffer);
mImageWidth and mImageHeight are the expected values so they are not this issue.
I put a for loop that looks at every element in mDisplayBuffer just before glDrawPixels call. No problem occurred here so the Access Violation doesn't seem to be coming from the mDisplayBuffer.
So it must be something within the glDrawPixels right?
I am using the TAO framework so that I can use C# and OpenGl.
What's the type of mDisplayBuffer ? Could it be being updated by another thread while the glDrawPixels is in progress, or relocated by the garbage collector (try a scoped lock around the DrawPixels call) ?
Related
In a program I am writing I work with images. I do several things with them and in the end (of a process) I invoke a function drawPicFrame
private void drawPicFrame(Bitmap bmp)
{
picImage.Image = bmp;
}
It works great. However when debugging, I have noticed that the pic control does not get updated until a operation is concluded and the GUI event loop is in charge. So for example say I put red dots all over the place in bmp in operation1() , and I put a breakpoint inside this operation1, these dots won't be seen until I leave operation1.
My question is, is there a way that I can update the bmp and see this reflected while I am still debugging?
(I know that I can modify my code so that instead of operation1 executing multiple loops, just execute one and then call drawPicFrame, but this involves a huge modification of the code just for debugging which is not ideal
if you can reach your control from that point in code, you can call picImage.Refresh() ... but please be aware that you should only do this on the UI thread (read: the thread that created picImage)
I've been all over the documentation and various samples, and all of my code appears to be as it should be.
However, I'm experiencing a memory leak that I cannot seem to plug. Here's what I know:
It happens when calling into an IAsyncOperation method and actually attach a .done or .then to the WinJS.Promise.
Leaking objects appear to include a Windows.Foundation.IAsyncOperation<T>, an AsyncOpPromise (dynamically created when the async method is called for the first time?) and most importantly, the result of the operation (T) which can be a very large object.
I can see the apparent leaks in the JavaScript memory profiler, no matter whether the result is a number, a string, or any other object type.
For example:
//This one leaks
document.getImageSourceAsync().done(function(source) {
//The intention is to do something with the image, but it doesn't really matter what does or does not happen here.
});
//This one doesn't leak
document.getImageSourceAsync();
I've created a sample project here: http://sdrv.ms/12TvPOa
Thank you in advance for any help.
Adam
I'm using D3DImage to show images rendered using Direct3D. The Direct3D rendering needs to be happening in its own thread, while the GUI thread takes a surface when it wants and puts it on the screen using D3DImage.
At first I tried to do this using a single D3D render target, however even with locks in place, I had serious tearing, i.e. the rendering thread was overwriting the surface as WPF was copying it on its frontbuffer. It seems like WPF is very unpredictable as to when it copies the data (i.e. it's not on D3DImage.Unlock() or even on the next D3DImage.Lock(), as the documentation suggests).
So now what I'm doing is I have two render targets, and every time WPF displays a frame, it asks the rendering thread to swap its targets. So I'm always rendering into the target WPF isn't using.
This means that on each graphical update of the window, I do something like
m_d3dImage.Lock();
m_d3dImage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, m_d3dRenderer.OutputSurface);
m_d3dImage.Unlock();
m_d3dRenderer.SwapSurfaces();
where OutputSurface is an IntPtr that points to the D3D render target we're not currently rendering to, and SwapSurfaces just swaps the two surface pointers and calls IDirect3DDevice9::SetRenderTarget with the one we'll use to render next.
EDIT: as requested, here is the code of SwapSurfaces():
var temp = m_renderingSurface;
m_renderingSurface = m_outputSurface;
m_outputSurface = temp;
m_d3dDevice.SetRenderTarget(0, m_renderingSurface);
Where m_renderingSurface and m_outputSurface are the two render targets (SharpDX.Direct3D9.Surface), and m_d3dDevice is the DeviceEx object.
This works beautifully, i.e. no tearing, however after a few seconds I get an OutOfMemoryException, and Direct3D has the following debug output:
Direct3D9: (ERROR) :Invalid iBackBuffer parameter passed to GetBackBuffer
Direct3D9: (ERROR) :Error during initialization of texture. CreateTexture failed.
Direct3D9: (ERROR) :Failure trying to create a texture
Direct3D9: (ERROR) :Error during initialization of texture. CreateTexture failed.
Direct3D9: (ERROR) :Failure trying to create a texture
MIL FAILURE: Unexpected HRESULT 0x8876017c in caller: CInteropDeviceBitmap::Present D3D failure
Direct3D9: (WARN) :Alloc of size 1577660 FAILED!
Direct3D9: (ERROR) :Out of memory allocating memory for surfaces.
Direct3D9: (ERROR) :Failure trying to create offscreen plain surface
I've found a related topic here where the proposed solution was to call D3DImage.SetBackBuffer() and pass IntPtr.Zero, however I've added this just before the existing call and it didn't solve the issue. I also tried calling Lock() and Unlock() around the SetBackBuffer(... IntPtr.Zero), and that didn't solve the issue either.
At this point I'm wondering if there's a bug in D3DImage or if I should use a different approach altogether. Could I replace my 2 render targets with a D3D swap chain instead, would that allow me to stop having to call SetBackBuffer with a different pointer all the time? I'm a newbie with Direct3D.
EDIT: I looked in the code of D3DImage.SetBackBuffer() using .NET Reflector, and it's creating an InteropBitmap every time. It doesn't do anything in particular for IntPtr.Zero. Since I'm calling this many times per second, perhaps the resources don't have the time to be freed. At this point I'm thinking of using 2 different D3DImages and alternating their visibility to avoid having to call their SetBackBuffer() all the time.
Thanks.
It appears that D3DImage creates a new Direct3D texture every time you set its backbuffer pointer to something different. This is eventually cleaned, but setting it 30 times per second like what I was doing doesn't leave it enough time, and is anyway a big performance killer. The approach I went for was to create several D3DImages, each with its own surface, put them all on top of each other and toggle their Visibility property so only one shows at a time. This seems to work very well and doesn't leak any memory.
I use a D3DImage to display images at a rapid framerate and ran into this same problem. I found out that D3DImage does create a new texture if you set the backbuffer pointer to a different pointer. But if you only change the backbuffer pointer's content (and not the pointer's address) it will not create a new texture.
Long story short, I inherited a fairly complex application and I'm trying to track down a memory leak involving a form. Right now, every time the form is closed and a new one brought up, the old one remains in memory. I tracked down an issue with a static event owned and set by a control within the program (apparently, so long as the static event was set, no instance of that control was considered out of scope, even when no one else referred to said controls). Now, I'm trying to track down the remaining issue.
Using MemProfiler and ANTS Memory Profile, I've learned that the root execution path goes like this:
FormOpenWatch <-- The item which remains active
System.EventHandler -- (this as Delegate)._target
System.Object[]
System.EventHandler -- (this as MultiCastDelegate)._invocationList
System.ComponentModel.EventHandlerList+ListEntry -- handler
System.ComponentModel.EventHandlerList+ListEntry -- next
System.ComponentModel.EventHandlerList+ListEntry -- next
System.ComponentModel.EventHandlerList+ListEntry -- next
System.ComponentModel.EventHandlerList+ListEntry -- next
System.ComponentModel.EventHandlerList -- head
PTU.MdiPTU -- (this as Component).events <-- The base application
Anyone have any insight for what I might be looking for? I've found a Shown event added with the base application, and ensured that it gets removed when the form is being disposed of, but that doesn't seem to have fixed the problem.
Much thanks for any help you can provide.
Later Edit: I have thought I've successfully solved this several times over now, and I'm still having issues. The problem seems to be stemming from my Plotter class (and various derived classes) having this "public static event MouseEventHandler MultiCursorMouseMove;" event. We have a "cursor" which displays the value and time of the graph at the mouse's location. Originally, this worked on one graph at a time, but a request was made to allow the user to toggle a mode where moving the mouse moved the plot across all of the displayed graphs. I wrote up an initial treatment hooking the EventHandlers in as the items were instantiated, and my partner across the pond rewrote it to use the static event, which gets assigned to each item on construction. His way is much more elegant and works better. All except that it's resulted in memory leaks. Using the memory profiling software has shown that every time I try to get rid of the form holding the plots, I'm left with a number of cases of "Disposed instance with direct EventHandler roots". In each of these, it shows that the object is either a Plotter, or an object pointed to by the Plotter. And, in each of these, the base link is that a MultiCursorMouseMove EventList points to these objects. I think that what's happening is that the Plotter is staying alive because it has this static event which in turn is linked to the Plotters. I have managed to verify that MultiCursorMouseMove is null through the debugger at a given point by virtue of my Dispose code removing the event for each Plotter, and yet running the profiler at that same point still shows this chain from MultiCursorMouseMove to these classes.
I'm out of ideas on how to fix this currently. Anyone?
If MdiPTU is the MDI parent form for your application, it sounds like FormOpenWatch might have subscribed to one of its events. If it hasn't done so directly, you might find the subscription in a FormOpenWatch superclass, or perhaps even in other code that can wire up execution of a FormOpenWatch method from an MdiPTU event.
We have an application that generates simulated data for one of our services for testing purposes. Each data item has a unique Guid. However, when we ran a test after some minor code changes to the simulator all of the objects generated by it had the same Guid.
There was a single data object created, then a for loop where the properties of the object were modified, including a new unique Guid, and it was sent to the service via remoting (serializable, not marshal-by-ref, if that's what you're thinking), loop and do it again, etc.
If we put a small Thread.Sleep( ...) inside of the loop, it generated unique id's. I think that is a red-herring though. I created a test app that just created one guid after another and didn't get a single duplicate.
My theory is that the IL was optimized in a way that caused this behavior. But enough about my theories. What do YOU think? I'm open to suggestions and ways to test it.
UPDATE: There seems to be a lot of confusion about my question, so let me clarify. I DON'T think that NewGuid() is broken. Clearly it works. Its FINE! There is a bug somewhere though, that causes NewGuid() to either:
1) be called only once in my loop
2) be called everytime in my loop but assigned only once
3) something else I haven't thought of
This bug can be in my code (MOST likely) or in optimization somewhere.
So to reiterate my question, how should I debug this scenario?
(and thank you for the great discussion, this is really helping me clarify the problem in my mind)
UPDATE # 2: I'd love to post an example that shows the problem, but that's part of my problem. I can't duplicate it outside of the whole suite of applications (client and servers).
Here's a relevant snippet though:
OrderTicket ticket = new OrderTicket(... );
for( int i = 0; i < _numOrders; i++ )
{
ticket.CacheId = Guid.NewGuid();
Submit( ticket ); // note that this simply makes a remoting call
}
Does Submit do an async call, or does the ticket object go into another thread at any stage.
In the code example you are reusing the same object. What if Submit sends the ticket in a background thread after a short delay (and does not take a copy). When you change the CacheId you are actually updating all the pending submits. This also explains why a Thread.Sleep fixes the problem. Try this:
for( int i = 0; i < _numOrders; i++ )
{
OrderTicket ticket = new OrderTicket(... );
ticket.CacheId = Guid.NewGuid();
Submit( ticket ); // note that this simply makes a remoting call
}
If for some reason this is not possible, try this and see if they are still the same:
ticket.CacheId = new Guid("00000000-0000-0000-0000-" +
string.Format("{0:000000000000}", i));
Thousands of developers use Guids in .NET. If Guid.NewGuid() had any tendency at all to get "stuck" on one value, the problem would have been encountered long ago.
The minor code changes are the sure culprit here. The fact that Thread.Sleep (which is less a red herring than a fish rotting in the sun) "fixes" your problem suggests that your properties are being set in some weird way that can't take effect until the loop stops blocking (either by ending or by Thread.Sleep). I'd even be willing to bet that the "minor change" was to reset all the properties from a separate thread.
If you posted some sample code, that would help.
It's a bug in your code. If you've managed to generate multiple guid's it is the most likely explanation. The clue is here in your question: "when we ran a test after some minor code changes to the simulator all of the objects generated by it had the same Guid"
See this article about how a Guid is created.
This artcile came from This answer.
Bottom line if you are creating the GUIDs too quickly and the clock hasn't moved forward that is why you are getting some as the same. However when you put a sleep in it works because the clock has moved.
The code in Submit and OrderTicket would be helpful as well...
You're reusing OrderTicket. I'd suspect that either you (or remoting itself) is batching calls out - probably in respect to # of connections/host limits - and picking up the last value of CacheId when it finally sends them along.
If you debug or Thread.Sleep the app, you're changing the timing so that the remoting call finishes before you assign a new CacheId.
Are you asyncing the remoting call? I'd think a sync call would block - but I'd check with a packet sniffer like Wireshark to be sure. Regardless, just changing to creating a new OrderTicket in each iteration would probably do the trick.
Edit: The question is not about NewGuid being broken...so my previous answer has been removed.
I dont know the details of how GUIDs are generated.. yet. However currently my org. is breeding GUIDs at a rate that would put rabbits to shame. So I can vouch for the fact that GUIDs aren't broken.. yet.
Post the source code if possible.. or a clone repro app. Many times I find the act of creating that clone app to repro the problem shows me the issue.
The other approach would be to comment out "those minor changes". If that fixes the problem, you can then triangularize to find the offending line of code. Eye-ball the minor changes hard... I mean real Hard.
Do let us know how it goes... this sounds interesting.
My gut is telling me something along these lines is going on...
class OrderTicket
{
Guid CacheId {set {_guid = new Guid("00000000-0000-0000-0000-");}
}
Log the value of CacheId into a log file every time its called with a stack trace ... Maybe someone else is setting it.