seit einiger Zeit bin ich damit beschäftigt unseren Code auf den MSVC lauffähig zu machen. Soweit so gut, nun habe ich bei einzelnen get/setPixel
Operationen ein merkwürdiges Problem bei nicht nativen Formaten (SHORT RGB(A) und FLOAT16). Führe ich meine UnitTests oder Demos aus, dann
wird die Applikation beim Setzen der Werte unter dem MSVC extrem stark verlangsamt (mehrere Sekunden) unter dem GCC läuft alles völlig normal,
in einem Bruchteil von Sekunden ab.
Da das ganze etwas schwierig zu erklären ist, hier ersteinmal die Code Fragemnte:
Code: Alles auswählen
void brImage::setPixelColor(const brRectangle<unsigned int>& rect, const brColor& color)
{
brPixelFormatInfo info = gfxUtils.getPixelFormatInfo(m_format);
unsigned int nativeColor = 0;
// if pixel format is native first calculate the native color before
// entering loop to set color value.
if(true==info.isNativeEndian()){
nativeColor = this->getNativePixelColor(color);
}
unsigned int bytesPerPixel = this->getBytesPerPixel();
for(unsigned int y = rect.getY(); y < rect.getY()+ rect.getHeight(); y++)
{
// calculation of the image value stride
unsigned int byteIndex = (this->getBytesPerRow() * y) + rect.getX() * bytesPerPixel;
for (unsigned int x = rect.getX(); x < rect.getX()+rect.getWidth(); x++)
{
if(true==info.isNativeEndian())
{
[...]
}
else{
switch(m_format)
{
// 32bit float value formats
case PF_FLOAT32_RGB:
{
m_data[byteIndex] = (unsigned char)color.getRed();
m_data[byteIndex + 1] = (unsigned char)color.getGreen();
m_data[byteIndex + 2] = (unsigned char)color.getBlue();
break;
}
case PF_SHORT_RGB:
{
unsigned int red, green, blue = 0;
brPixelFormatInfo info = gfxUtils.getPixelFormatInfo(PF_SHORT_RGB);
brPixelFormatInfo::RGBA_BITS bits = info.getBitValues();
brColor::RGBA rgba = color.getRGBA();
red = gfxUtils.convertColorToFixedPoint(rgba.m_red, bits.m_red);
green = gfxUtils.convertColorToFixedPoint(rgba.m_green, bits.m_green);
blue = gfxUtils.convertColorToFixedPoint(rgba.m_blue, bits.m_blue);
m_data[byteIndex] = (unsigned char)red;
m_data[byteIndex + 1] = (unsigned char)green;
m_data[byteIndex + 2] = (unsigned char)blue;
break;
}
// half float precision values
case PF_FLOAT16_R:
{
brColor::RGBA rgba = color.getRGBA();
m_data[byteIndex] = (unsigned char)gfxUtils.convertColorToHalfFloat(rgba.m_red);
break;
}
default:
throw brCore::brIllegalStateException(
"[brImage]::setPixelColor: Invalid pixel format!");
}
}
byteIndex += bytesPerPixel;
}
}
}
Code: Alles auswählen
unsigned int brGraphicsUtils::convertColorToFixedPoint(float color, unsigned int bits) const
{
unsigned int fixed = 0;
if(color <= 0.0f){
fixed = 0;
}
else if (color >= 1.0f){
fixed = (1U<<bits)-1U;
}
else{
fixed = (unsigned int)(color * (1U<<bits));
}
return fixed;
}
in Einzelschritten über die Aufrufe husche, wirkt alles "normal" schnell, die Aufrufe kommen schnell zurück. Rufe ich in meinem Test jedoch die
setPixelColor Methode als Prozedurschritt auf, dann dauert es etwa 1-3Sek. bevor der Aufruf aus der Methode zurückkehrt ...
Zur Evaluierung habe ich mal an der SHORT_RGB Auswertung Messpunkte eingebaut die mir die Systemzeit vor und nach den Operationen bzw.
beim betreten und Verlassen der Methode liefern:
Es sieth so aus, als ob die Konvertierung nicht der Kasus Knaxus ist, sondern das das Schreiben der Daten einiges an Zeit schluckt. Aber- in: 2012-Jan-19 15:44:52.664127
- start convert: 2012-Jan-19 15:44:52.669127
- end convert: 2012-Jan-19 15:44:52.690127
- start writing: 2012-Jan-19 15:44:52.695127
- end writing: 2012-Jan-19 15:44:52.700127
- out: 2012-Jan-19 15:44:52.705127
das bei den simplen Aufrufen? Ich kann mir das ganze nicht mehr erklären und warum nur auf dem MSVC? Unter dem GCC läuft der Code
sowohl für Linux als auch Windows flott durch ... Es betrifft auch nur die SHORT_RGB, SHORT_RGBA und FLOAT_16 Formate, die FLOAT32
Formate gehen problemlos durch ...
Hat jemand evtl. eine Idee was hier schief laufen könnte? Mir gehen allmählich die Ideen aus ...
Gruß
Hellhound
P.s: Den gesamten Code kann man hier einsehen:
http://binrevengine.svn.sourceforge.net ... hound-dev/