[Solved] Locking pixel buffer crashes application

tafkag

26-01-2010 10:38:51

Hello everyone,

first of all a big thank you to all the Mogre contributors. You really do a great job with this project!
And thanks in advance to everyone who reads this lengthy post.

I'm trying to create a texture out of a byte array to vizualize some data and most of the time, everything works as expected. But at some point, the application throws an AccessViolationException and crashes. I can't really reproduce this behaviour, which doesn't make debugging any easier - sometimes the application runs for hours without crashing, at other times the problem occurs within minutes.

Here is what I'm doing. This is called once every frame to update _Texture (which is of type TexturePtr).


public void RenderForceImage()
{
double fPlateResolution = _forcePlate.PressureResolution;
int yStart = (int)(_Texture.Height / 2) - (int)(_forcePlate.Height / 2);
int xStart = 1;

HardwarePixelBufferSharedPtr pixBuf = _Texture.GetBuffer();
PixelBox pixBox;
byte[] datacopy = new byte[_forcePlate.Data.Length];
Array.Copy(_forcePlate.Data, datacopy, _forcePlate.Data.Length);
unsafe
{
fixed (byte* data = datacopy)
{
try
{
// EXCEPTION IS THROWN HERE!
pixBuf.Lock(HardwareBuffer.LockOptions.HBL_NORMAL);
}
catch
{
return;
}

pixBox = pixBuf.CurrentLock;
byte* buffer = (byte*)pixBox.data.ToPointer();

for (int y = 0; y < _forcePlate.Height; y++)
for (int x = 0; x < _forcePlate.Width; x++)
{
int dataPos = y * _forcePlate.Width + x;
int texPos = (y + yStart) * (int)_Texture.Width + (x + xStart);
int bufPos = 4 * texPos;

byte pressureVal = (byte)(System.Math.Min(data[dataPos] * fPlateResolution * _boosFac, 255));

ColourValue cv = Projector.ColorMap[pressureVal];

buffer[bufPos] = (byte)cv.b;
buffer[bufPos + 1] = (byte)cv.g;
buffer[bufPos + 2] = (byte)cv.r;
buffer[bufPos + 3] = (byte)(pressureVal > 0 ? 255 : 0);

}

pixBuf.Unlock();
}
}
pixBuf.BlitFromMemory(pixBox, pixBox.box);
_pixelBox = pixBox;
}


The exception is thrown when locking the pixel buffer:

pixBuf.Lock(HardwareBuffer.LockOptions.HBL_NORMAL);


I observed that the UseCount property of the pixBuf explodes before the exception occurs (it normally cylces between 2-200 but in the "crash-frame" it's somewhere over 300 million). Also, if I break at the exception and let the debugger dig into the properties of the pixBuf object, the Target property seems to be in an invalid state (debugger shows an exception when trying to display the value of the property).

I was running Mogre 1.4.8 but recently updated to 1.6.4 which didn't solve the problem. The only difference seems to be, that the application doesn't crash any more, but once the error has occured, the exception is thrown in every following frame and the texture doesn't get updated any more.

I tried to reinitialize the texture in the catch-block...

catch
{
_Texture.Dispose();
_Texture = null;
_Texture = TextureManager.Singleton.Load(ResourceName, Renderer.Instance.DefaultGroupName);

_Texture.Format = PixelFormat.PF_BYTE_RGBA;
_Texture.Usage = (int)TextureUsage.TU_DYNAMIC_WRITE_ONLY_DISCARDABLE;
return;
}

...but the exception reoccurs in the next frame anyway.

I tested everything on various machines and got the same results every time (I'm under the impression it crashes more often on certain machines than on others, but I it crashes on all machines). I ran out of ideas a long time ago, so every tiny hint is really appreciated. There is a old thread in the ogre forum, which describes the same behaviour, but unfortunatly, no solution was found and somehow I'm guessing it's an Mogre problem (but I'm obviously not sure, though...).

smiley80

26-01-2010 14:08:05

Dispose pixBuf after you unlock it.

pixBuf.BlitFromMemory(pixBox, pixBox.box);
That seems to be redundant, because you've already written to the buffer.

tafkag

26-01-2010 14:29:56

That seems to be redundant, because you've already written to the buffer.

You're absolutely right. I've removed the BlitFromMemory line and added disposing of the pixBuf after unlocking it. The application is running fine....I'm starting some tests now to determine if the exception still occurs.

Thank you - that already helped a lot! :)

tafkag

28-01-2010 14:51:18

Ok, even after extensive testing, the exception didn't occur again, so I'm starting to believe the problem is fixed.

A big THANK YOU to you smiley80 - this one really bugged me for a long time.