Hi,
I have done two programs that do the same thing one in JAVA the other in C++ with SDL.
My JAVA program seems to be faster that the SDL one.
Because it doesn’t sound good I sure I miss something in SDL?
Could you tell me where my mistake is?
The code is very simple:
It loads 2 images (640x480)
It blits the more picture’s part it can, in one second. (if it adds blit a full image then it will switch to the other one)
Then it print the number of pictures blitted and the size of those pictures
Here is the C++ SDL code
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <SDL.h>
#include
using namespace std ;
class Measurements{
// Screen size
static const int _ScreenWidth;
static const int _ScreenHeight;
static const string _Image;
static const string _Image2;
// Number of test per picture size
static const int _NbTestPerSize;
public:
Measurements(){
_BlitedPictureWidth = 1;
_BlitedPictureHeight = 1;
_NumTest = 1;
_NumTestPerSize = 0;
_NumPicturePerSecond = 0;
printf("Trying to Load the picture \"%s\"\n",_Image.c_str());
printf("Trying to Load the picture \"%s\"\n",_Image2.c_str());
// Load the picture
_Map = SDL_LoadBMP(_Image.c_str());
_Map2 = SDL_LoadBMP(_Image2.c_str());
if( !_Map || !_Map2)
exit(3);
}
~Measurements(){
delete(_Map);
delete(_Map2);
}
bool isFinish(){
return ((_NumTest == 101)?true:false);
}
void paint(SDL_Surface* pSurface){
int s=0; // Number of small picture drew
int n=0; // Number of full picture drew
int modulo = 0;
int max = 0;
// Define the first picture to be drew
SDL_Surface* theMap = _Map;
// Define some constant
modulo = _ScreenWidth/_BlitedPictureWidth;
max = (_ScreenWidth/_BlitedPictureWidth)*(_ScreenHeight/_BlitedPictureHeight);
time_t tnewTime, toldTime;
SDL_Rect sdlSrc, sdlDst;
time(&toldTime);
do{
// the Src is a part of the picture [ (blitted picture size)*horizontal position, (blitted picture size)*vertical position]
sdlSrc.x = _BlitedPictureWidth*(s%modulo);
sdlSrc.y = _BlitedPictureHeight*(int)(s/modulo);
sdlSrc.w = _BlitedPictureWidth;
sdlSrc.h = _BlitedPictureHeight;
// the Dst is a part of the picture [ (blitted picture size)*horizontal position, (blitted picture size)*vertical position]
sdlDst.x = sdlSrc.x;
sdlDst.y = sdlSrc.y;
SDL_BlitSurface(theMap, &sdlSrc, pSurface, &sdlDst );
// one picture have been fully drewn -> draw the other picture
if (++s>max){
s=0;
theMap = ((++n)%2 == 0)?_Map:_Map2;
}
time( &tnewTime );
// Draw during 1 second
}while( tnewTime - toldTime<1);
// Add the number of picture draw during this test
_NumPicturePerSecond += s + n*max;
// If the test is finish
if ((++_NumTestPerSize) == _NbTestPerSize){
_NumTestPerSize = 0;
// Print the number of picture drew in one second
long picPerSec = _NumPicturePerSecond/_NbTestPerSize;
printf("[%d, %d] => %d pic/sec => %d pix/sec\n", _BlitedPictureWidth, _BlitedPictureHeight, picPerSec, (picPerSec*_BlitedPictureWidth*_BlitedPictureHeight));
// Increase the number of test done
_NumTest++;
// Reset variable
_NumPicturePerSecond = 0;
// Define the properties of the next test
_BlitedPictureWidth = (_NumTest*_ScreenWidth)/100;
_BlitedPictureHeight = (_NumTest*_ScreenHeight)/100;
}
}
private:
// First picture propertie
SDL_Surface* _Map;
// Second picture propertie
SDL_Surface* _Map2;
// Size of the blited picture
int _BlitedPictureWidth;
int _BlitedPictureHeight;
// Current number test
int _NumTest;
// Current number of test for the current size
int _NumTestPerSize;
// Number of picture drew since the begining of the current test
long _NumPicturePerSecond;
};
const int Measurements::_ScreenWidth = 640;
const int Measurements::_ScreenHeight = 480;
const string Measurements::_Image = “at 640x480.bmp”;
const string Measurements::_Image2 = “box 640x480.bmp”;
const int Measurements::_NbTestPerSize = 1;
int main (int argc, char *argv[])
{
SDL_Surface * sdlMainScreen;
if (SDL_Init (SDL_INIT_VIDEO) < 0)
exit (1);
SDL_VideoInfo * pVideoInfo;
pVideoInfo = const_cast<SDL_VideoInfo*>(SDL_GetVideoInfo());
char namebuf[256];
SDL_VideoDriverName(namebuf, 256);
atexit(SDL_Quit);
sdlMainScreen = SDL_SetVideoMode (640, 480, 16, SDL_HWSURFACE | SDL_DOUBLEBUF);
pVideoInfo = const_cast<SDL_VideoInfo*>(SDL_GetVideoInfo());
if (sdlMainScreen == NULL)
exit (2);
Measurements measurements;
while (!measurements.isFinish()){
SDL_Event event;
while (SDL_PollEvent (&event));
// draw
measurements.paint(sdlMainScreen);
// Flip the buffers
SDL_Flip(sdlMainScreen);
}
SDL_Quit();
return 0;
}
Here is the java code:
import java.awt.; // Class [ Graphics, Graphics2D, Image, Color, Toolkit, MediaTracker ]
import java.awt.image.; // Class [ ImageObserver, BufferedImage ]
import javax.swing.*; // Class [ JFrame, MediaTracker ]
import java.net.URL; // Class [ URL ]
/*
import sdl.core.Main;
import org.havi.ui.HScene;
public class Measurements extends HScene implements ImageObserver{
*/
public class Measurements extends JFrame implements ImageObserver{
// Screen size
final int m_ScreenWidth = 640;
final int m_ScreenHeight = 480;
// Number of test per picture size
final int m_NbTestPerSize = 1;
public static void main(String[] args){
long initTime, initMem;
// Free all unused memory - gc for Garbage Collector -
System.gc();
// // !!!!PERFORMANCE TRACKING!!!!
initTime = System.currentTimeMillis();
initMem =Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory();
System.out.println("H INIT TIME: "+initTime+"ms MEMORY: "+(double)initMem/1000+"k");
// // !!!!PERFORMANCE TRACKING!!!!
// Load the program
Measurements program = new Measurements();
long start = System.currentTimeMillis();
// Refreshing loop
do{
if (program.m_Status == READY)
program.paint(program.getGraphics());
}while(program.m_Status != TEST_FINISH);
long stop = System.currentTimeMillis();
System.out.println("total time = "+(stop-start)+" ");
// // !!!!PERFORMANCE TRACKING!!!!
System.out.println("PREFETCH INIT TIME: +"+((System.currentTimeMillis()-initTime))+
"ms MEMORY: +"+((double)(Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory()-initMem))/1000 +"k");
// Free all unused memory - gc for Garbage Collector -
System.gc();
System.out.println("PREFETCH GC TIME: +"+((System.currentTimeMillis()-initTime))+
"ms MEMORY: +"+((double)(Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory()-initMem))/1000 +"k");
// // !!!!PERFORMANCE TRACKING!!!!
program.quit();
}
public Measurements(){
m_BufferedImage = new BufferedImage( m_ScreenWidth, m_ScreenHeight, BufferedImage.TYPE_INT_ARGB);
Graphics gr = m_BufferedImage.getGraphics();
m_Graphics2D = (Graphics2D)gr;
m_Image = m_Image+ " " +m_ScreenWidth+"x"+m_ScreenHeight+".jpg";
m_Image2 = m_Image2+ " " +m_ScreenWidth+"x"+m_ScreenHeight+".jpg";
System.out.println("Trying to Load the picture \""+m_Image+"\"");
System.out.println("Trying to Load the picture \""+m_Image2+"\"");
// Load the 2 pictures into the maps
URL imgURL = getClass().getResource(m_Image);
URL imgURL2 = getClass().getResource(m_Image2);
Toolkit tk = Toolkit.getDefaultToolkit();
try {
MediaTracker m = new MediaTracker(this);
m_Map = tk.getImage(imgURL);
m_Map2 = tk.getImage(imgURL2);
m.addImage(m_Map, 0);
m.addImage(m_Map2, 0);
m.waitForAll();
System.out.println("Loaded picture \""+m_Image+"\" ["+m_Map.getWidth(this)+", "+m_Map.getHeight(this)+"]");
System.out.println("Loaded picture \""+m_Image2+"\" ["+m_Map2.getWidth(this)+", "+m_Map2.getHeight(this)+"]");
}
catch (Exception e) {
e.printStackTrace();
}
//close the window
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(new java.awt.Dimension(m_ScreenWidth, m_ScreenHeight));
//this.setLayout(null);
this.setBackground(Color.gray);
this.setVisible(true);
}
public void paint(Graphics g){
int s=0; // Number of small picture draw
int n=0; // Number of full picture draw
int modulo = 0;
int max = 0;
// Exit it it is currently refreshing
if (m_Status == 0) return;
// Disable refresh
m_Status = REFRESHING;
// Define the first picture to be draw
Image theMap = m_Map;
// Define some constant
modulo = m_ScreenWidth/m_BlitedPictureWidth;
max = (m_ScreenWidth/m_BlitedPictureWidth)*(m_ScreenHeight/m_BlitedPictureHeight);
long oldTime = System.currentTimeMillis();
do{
m_Graphics2D.drawImage( theMap,
(m_BlitedPictureWidth*(s%modulo)), (m_BlitedPictureHeight*(int)(s/modulo)),
(m_BlitedPictureWidth+m_BlitedPictureWidth*(s%modulo)) , (m_BlitedPictureHeight+m_BlitedPictureHeight*
(int)(s/modulo)),
m_BlitedPictureWidth*(s%modulo), m_BlitedPictureHeight*(s/modulo),
m_BlitedPictureWidth*(s%modulo) +m_BlitedPictureWidth, m_BlitedPictureHeight + m_BlitedPictureHeight*
(s/modulo),
Color.black,
this);
// one picture have been fully drawn -> draw the other picture
if (++s>max){
s=0;
n++;
theMap = ((n)%2 == 0)?m_Map:m_Map2;
}
// Draw during 1 second
}while( System.currentTimeMillis() - oldTime<1000);
// Add the number of picture draw during this test
m_NumPicturePerSecond += s + n*max;
// If the test is finish
if ((++m_NumTestPerSize) == m_NbTestPerSize){
m_NumTestPerSize = 0;
// Print the number of picture draw in one second
long picPerSec = m_NumPicturePerSecond/m_NbTestPerSize;
System.out.println("["+m_BlitedPictureWidth+", "+m_BlitedPictureHeight+"] => "+picPerSec+" pic/sec => "+(picPerSec*m_BlitedPictureWidth*m_BlitedPictureHeight)+" pix/sec");
// Increase the number of test done
m_NumTest++;
// Reset variable
m_NumPicturePerSecond = 0;
// Define the properties of the next test
m_BlitedPictureWidth = (m_NumTest*m_ScreenWidth)/100;
m_BlitedPictureHeight = (m_NumTest*m_ScreenHeight)/100;
}
// Blit the buffer
g.drawImage(m_BufferedImage, 0, 0, m_ScreenWidth, m_ScreenHeight, this);
// If the test have been completed
if (m_NumTest == 101) m_Status = TEST_FINISH; else m_Status = READY;
}
// Quit properly the program
public void quit(){
/*
Toolkit toolkit = Toolkit.getDefaultToolkit();
Main main = toolkit.getMain();
toolkit.terminate();
main.TTFQuit();
main.SDLQuit();
*/
System.exit(0);
}
// First picture propertie
String m_Image = new String("at");
Image m_Map = null;
// Second picture propertie
String m_Image2 = new String("box");
Image m_Map2 = null;
// Size of the blited picture
int m_BlitedPictureWidth = 1;
int m_BlitedPictureHeight = 1;
// Current number test
int m_NumTest = 1;
// Current number of test for the current size
int m_NumTestPerSize = 0;
// Number of picture draw since the begining of the current test
long m_NumPicturePerSecond = 0;
// Is it ready for a refresh
public int m_Status = 1;
public BufferedImage m_BufferedImage;
public Graphics2D m_Graphics2D;
// Constant
static final int REFRESHING = 0;
static final int READY = 1;
static final int TEST_FINISH = 2;
}