So while on win32 builds everything twice slower, on amigaos4 everything just stops :)
Yeah, it mean that this sdl2 migration doing something very wrong, and strangely on amigaos4 it not just twice slower, but almost stop everything.
I think its about CIrrDeviceSDL::present() realisation and how the surface and blitting done, see there some SDL_CreateRGBSurfaceWithFormatFrom with SDL_PIXELFORMAT_ARGB8888 as default , and some strange SDL_RenderCopy().. Imho something there cause those heavy issues (And still strange, why on amigaos4 it made not just slower, but just everything about to stop, mouse jerky, whole system overloaded, etc).
It allocates (and frees) 2 surfaces per frame! There should be just a pre-allocated streaming texture which gets updated once per frame and finally presented.
At the moment I don't have time to check it more but the implementation just looks very slow and pointless.
At the moment I don't have time to check it more but the implementation just looks very slow and pointless.
In general it just copy of SDL1 version, just he tried to port it to SDL2 .. And the only real difference is that CIrrDeviceSDL::present() realisation with re-copy of 2 surfaces, etc.
I tried to play with it by commenting out parts,etc, but its just slow all the time, even if i keep only one surface.. If you will have time, maybe you can give a try to fix that part ? If all will be same by speed as with sdl1, we can get rid of sdl1 there, and maybe it automatically will fix "windowactive" issue too. Plus having SDL2 for all new stuff always better today..
But the above code is not compiled. I'm assuming here that the incoming data ("surface") is of same size and format as texture ("ScreenTexture").
Well, that definately the way to do how you show it. I just copy+paste your code, without any creation of sdlsurface. And it even render something to the window (just half of the window , and with wrong colors), but it renderes for sure, and speed is MUCH better.
Should't somewhere sdlsurface be created at all , or , there is no needs for ?
And how to deal with "format" then, probabaly still need to call SDL_LockTexture ?
Ideally, Irrlicht should be configured to render to an ARGB "surface" (I mean video::IImage, not SDL_Surface) which could be then uploaded to the texture. SDL_Surface would be only an extra step and hopefully unnecessary.
Ideally, Irrlicht should be configured to render to an ARGB "surface" (I mean video::IImage, not SDL_Surface) which could be then uploaded to the texture. SDL_Surface would be only an extra step and hopefully unnecessary.
I think we can't rewrite irrlicht a lot, it will bring other problems imho. Its pretty heavy , and the more things to change in other files can lead to problems we will not see from first look :)
At least, if with SDL1 it was with SDL_Surface, and it even was allocated each frame, maybe at first we can do same with SDL2, and then, thinking about how to get rid of it for speed.
Quote:
Do you know how to configure Irrlicht renderer?
Its not configured as i can tell, you just choice what one to compile in. Everything controlled from one include file : include/irrCompileconfig.h
Quote:
So this is SW renderering, how about HW? I suppose Irrlicht speaks also OpenGL?
Yeah sure OpenGL (over gl4es, minigl too old for). gl4es usage was the main point why i working on it. I made a port year ago, just now want to make it "all allright" for release, to have and opengl, and software renders works (software rendering will help for example those ones who don't have ogles).
Initially Irrlicht support those drivers:
software rendering burning video (same as software, just more accurate) directx 8 & 9 opengl
you can configure to use or one of them, or all of them, or some of them, etc.
Also, it can be configured to which device do render things. And initially Irrlicht support those: SDL1, win32 and X11.
So, you can mix it all you want. Just choice what drivers to compile in , and which device use with.
And as whole Irrlicht now progress veeery slow, all the tries like adding SDL2, or OpenGLES2 support, done by those random patches there and there by ppls who don't test things much, and "oh, i made it works ! its enough".
And before i can go route like "sdl2 + opengl" on amigos4, i firstly need to made "sdl2+software rendering" works on both, amigaos4 and win32 (and be the same or better by speed as sdl1), and then, when all works on both oses, i can add opengl there (for both oses again, so can test differences between, etc).
And as next step i will try to add opengles2 directly without opengl (and so gl4es), but firstly need that software rendering to be sure that SDL2 rewrite works as expected , and then all other work can be done on top of it.
PS. ah, and what i forget to tell : i do all tests on 1.8.4 irrlicht. That link where SDL2 patch placed, are from unfinished 1.9.0 release. Its all the same, just there is no surface->getData() , but surface->lock() instead. So i had to change it.
Its in include/IImage.h and relevant part are:
//! Use this to get a pointer to the image data.
/**
\return Pointer to the image data. What type of data is pointed to
depends on the color format of the image. For example if the color
format is ECF_A8R8G8B8, it is of u32. */
void* getData() const
{
return Data;
}
//! Lock function. Use this to get a pointer to the image data.
/** Use getData instead.
\return Pointer to the image data. What type of data is pointed to
depends on the color format of the image. For example if the color
format is ECF_A8R8G8B8, it is of u32. Be sure to call unlock() after
you don't need the pointer any more. */
_IRR_DEPRECATED_ void* lock()
{
return getData();
}
but that for unfinished 1.9.0, for 1.8.4 there was only surface->lock():
I mean that video::IImage surface has to be ARGB8888 format or texture updating fails. This surface is created somewhere, and maybe it uses totally different format for some reason. You can use printf to debug bitmasks, for example, then we know what's there.
Well, if consider that we use not surface->getdata() from 1.9.0, but surface->lock() from 1.8.4, then that what writen in IImage.h about:
//! Lock function. Use this to get a pointer to the image data.
/** After you don't need the pointer anymore, you must call unlock().
\return Pointer to the image data. What type of data is pointed to
depends on the color format of the image. For example if the color
format is ECF_A8R8G8B8, it is of u32. Be sure to call unlock() after
you don't need the pointer any more. */
So they do check what video formats textures have, and set sdlSurface's format to necessary value because of this. Question is what and to which we need to set, if we don't use sdlSurface. I.e. can we call SDL_UpdateTexture()+SDL_RenderCopy() with necessary format taken from the above check ?
I just removed from the above checks all sdlSurfaces sets, and just put prinfs, so in our case (i.e. with your code and when it draws half of screen with wrong colors), its video::ECF_A1R5G5B5 format. That explain probably "half of screen" drawing and wrong colors as well. Need somehow to tell to SDL_UpdateTexture()+SDL_RenderCopy() what format we use.
@Capehill I think that check on formats need be added rigth before SDL_CreateTexture() , but strange that this one called inside of CIrrDeviceSDL::resizeWindow ! And that function didn't have any surface::IImage, so i can't there to that check and put necessary value for format.
It would be interesting to know would Irrlicht work nicely if this hard-coded format was changed to 32-bit. Maybe it's slower to render 32-bit but it should look nicer too.
Second option is to modify texture format to 16-bit (same as Irrlicht's). But not even SDL software renderer support this exact format with 1-bit alpha so it means (as far as I know) that SDL will do colour conversion step during texture update.
Third option is to manually convert colour format but I don't like this one.
Quote:
Need somehow to tell to SDL_UpdateTexture()+SDL_RenderCopy() what format we use.
No. We have already told SDL which colour format we want to use when we created the texture. It is application's responsibility to provide valid data.
I don't understand why, because if I'm reading the correct code, Irrlicht SW renderer is hard-coded to 16-bit: https://github.com/okuoku/irrlicht-gen ... t/CSoftwareDriver.cpp#L33
I think its done for simplifity things and for speed. Software rendering mostly used for some test probably and for comparing things, it probabaly just have no needs to be 32bit aware.
Quote:
It would be interesting to know would Irrlicht work nicely if this hard-coded format was changed to 32-bit. Maybe it's slower to render 32-bit but it should look nicer too.
Its already not that fast on amigaos4 as it should be, because of all kind of reassons (i will post benchmarks later in some other thread), so make it be even more slower even in software rendering imho no go. Its just on level of old 1.6ghz amd :) (Probably because of missing DMA in graphics.library as well as anything else). But probabaly for theoretical reassons and for checks, it can be intersting to play with..
Quote:
Second option is to modify texture format to 16-bit (same as Irrlicht's). But not even SDL software renderer support this exact format with 1-bit alpha so it means (as far as I know) that SDL will do colour conversion step during texture update.
Third option is to manually convert colour format but I don't like this one.
What i mean, is that we do call SDL_CreateTexture() with some image format. So, all we need there, is to check what image format we have, and put it to the SDL_CreateTexture() instead of SDL_PIXELFORMAT_ARGB8888.
I think about something like this:
void CIrrDeviceSDL::resizeWindow(u32 x, u32 y)
{
if (ScreenWindow)
{
SDL_SetWindowSize(ScreenWindow, x, y);
}
if (ScreenTexture)
{
SDL_DestroyTexture(ScreenTexture);
ScreenTexture = NULL;
}
But that didn't work, as at moment when this resizeWindow() is called , it seems that image's surface didn't containt necessary format, and it return ECF_R8G8B8 sadly.. Maybe just code need to be restuctured a little, so when we will call SDL_CreateTexture() format of image's surface will be known, and so all will works.
@Capehill I now understand why they in SDL1 (and in that SDL2 patch) version do check on all things (i.e. on argb8888 as well, and on rgb565, not only a1555): because Irrlicht have 2 different software renderers. One called exactly like that "softwarerenderer" but its not very accurate. And another one, called "BurningsVideo", which is also software renderer, but this one much more accurate. And there is his file : CSoftwareDriver2.cpp (see 2 at end)
So, when you use SDL in irrlicht, you may choice and "software renderer" and "burnings video", which boch software. And while in first one, a1555 are hardcoded, second one maybe more accurate in that terms.
As said its ok on win32, same as sdl1 by speed. Just on amigaos4 by some reassons give 2-3 fps. Maybe something with events, which somehow ok for win32 and not for aos4 ?
Is there difference between accelerated and software renderer?
Tried to replace SDL_CreateRenderer(ScreenWindow, -1, 0); on SDL_CreateRenderer(ScreenWindow, -1, SDL_RENDERER_ACCELERATED); give no changes visually, same.
What i can't get currently, its why on win32 in terms of speed there is not such massive slowdown with 1:1 same code. We test pretty much of SDL2 apps already over our SDL2 , so strange..
On win32 when i put the same measure code, i have such output:
//! Restore original window size
void CIrrDeviceSDL::restoreWindow()
{
// do nothing
}
//! returns if window is active. if not, nothing need to be drawn
bool CIrrDeviceSDL::isWindowActive() const
{
return (WindowHasFocus && !WindowMinimized);
}
//! returns if window has focus.
bool CIrrDeviceSDL::isWindowFocused() const
{
return WindowHasFocus;
}
//! returns if window is minimized.
bool CIrrDeviceSDL::isWindowMinimized() const
{
return WindowMinimized;
}
//! Set the current Gamma Value for the Display
bool CIrrDeviceSDL::setGammaRamp( f32 red, f32 green, f32 blue, f32 brightness, f32 contrast )
{
return false;
}
//! Get the current Gamma Value for the Display
bool CIrrDeviceSDL::getGammaRamp( f32 &red, f32 &green, f32 &blue, f32 &brightness, f32 &contrast )
{
return false;
}
//! returns color format of the window.
video::ECOLOR_FORMAT CIrrDeviceSDL::getColorFormat() const
{
return CIrrDeviceStub::getColorFormat();
}
} // end namespace irr
#endif // _IRR_COMPILE_WITH_SDL1_DEVICE_
As you can see there is almost no code left, but it works as expected on win32 (same speed as for sdl1, etc). On amigaos4 the same 1:1 code copied and compiled in, bring some madness-move of camera, without stop. Like i move mouse fast fast everywhere. At least visually.
Then, once i add check/set on "focus", i.e. to make run() be like this:
//! runs the device. Returns false if device wants to be deleted
bool CIrrDeviceSDL::run()
{
os::Timer::tick();
postEventFromUser(irrevent);
break;
case SDL_WINDOWEVENT:
switch (SDL_event.window.event)
{
case SDL_WINDOWEVENT_ENTER:
case SDL_WINDOWEVENT_FOCUS_GAINED:
printf("we got events about focus=true\n");
fflush(stdout);
WindowHasFocus = true;
break;
case SDL_WINDOWEVENT_LEAVE:
case SDL_WINDOWEVENT_FOCUS_LOST:
printf("we got events about focus=false\n");
fflush(stdout);
WindowHasFocus = false;
break;
}
break;
case SDL_QUIT:
Close = true;
break;
default:
break;
} // end switch
} // end while
return !Close;
}
Then everything stops, and i have 1-2 fps. On win32, all works as before, without visuall change of course. With or without focus check/set it have the same fps. But on amigaos4 without check everything moves fast-fast, but with check, everything stops.
It looks like something with mouse / focus code in our sdl2 cause this. Maybe the fact that without "focus" value being checked/set everything just start moves like a madman, and that when i put back focus checks and it all start to be slow like hell, are the roots of the same issue ?
EDIT: interesting, that when i run that code with set/check on focus, but didn't set it, only printfs , then i can see that for win32, when i run app, it just says:
we got events about focus=true we got events about focus=false
And nothing more.
But if i run it under amigaos4, its flood me with those entries without stop until i move mouse. Something pretty different there between our and win32 sdl2 ports.
As i say its just i have now 2 files (sdl1 ones and sdl2 ones), which i just copy to win32 vesion and to amigaos4 version. And with win32 version it all works, speed same in both versions. On amigaos4, sdl1 one ok, and sdl2 : when set on windowfocus used : 2 fps. When no set, then like i move mouse fast-fast in all the directions.
EDIT2: Oh, and i go pretty close now : i found that if i just change creating of sdl_window be SDL_FULLSCREEN one, then both bugs gone ! I.e. in fullscreen everything works and when i check/set focus, and when i didn't. In boch cases all renders fine, speed the same, and no flood of those "true/false". In other words, issue is with window mode only, and only on amigaos4 side (with the same 1:1 sdl2 code)
Edited by kas1e on 2019/8/26 13:30:22 Edited by kas1e on 2019/8/26 13:36:52 Edited by kas1e on 2019/8/26 14:04:59 Edited by kas1e on 2019/8/26 14:06:04 Edited by kas1e on 2019/8/26 14:08:21 Edited by kas1e on 2019/8/26 14:14:51 Edited by kas1e on 2019/8/26 14:47:09 Edited by kas1e on 2019/8/26 16:22:59