Menu

#326 SDL2 UI

future
open
nobody
UI (9)
5
2023-06-19
2014-08-23
No

Hi All!

Here is a patch to add SDL2 UI to FUSE.

We could observe a significant rendering speed improvement compared to SDL1 UI. I made some test on a debian linux (H61 mainboard, Celeron G550@2.60GHz, Sandy Bridge HD 2000 GPU).

GTK UI may do better performance, because my desktop run on 32bit RGB visual like GTK UI. SDL and X UIs work on RGB565 so underlaying driver or fuse has to do extra RGB565->RGB888 conversions...


Results:

OPIUM4K demo: ./fuse SHOCK.TAP -m 128 -g hq3x --speed 1000
SHOCK demo part 2: ./fuse SHOCK.TAP -m se -g hq2x --speed 1000
SHOCKPEN demo part 4: ./fuse SHOCKPEN.SCL -m pentagon -g hq3x --speed 1000
SHOCKPEN demo part 4(T): ./fuse SHOCKPEN.SCL -m pentagon -g 3x --speed 1000
SHOCK demo part 2(X): ./fuse SHOCK.TAP -m se -g timex15x --speed 1000

Table of measured emulation speeds:

TEST SDL SDL2/max GTK X11 XV
OPIUM4K 138% 216%/215% 240% 129% 112%
SHOCK 35% 49%/49% - - -
SHOCKP 62% 98%/94% 100% 57% 50%
SHOCKP T 166% 368%/317% 345% 157% 133%
SHOCK X 166% 355%/310% 320% 152% 132%

Note: OPIUM4k is Opium (4k intro), SHOCK is Shock Megademo from WOS, SHOCKP is Shock Megademo (Pentagon Fix). From SHOCK/SHOCKPEN i used the 'border stripes' part of the demo. T is 'Triple size', X is 'Timex 1.5x' filter.

Note: The second value in SDL2 column measured with maximized window (1400x1050)

Note: There is no practical difference between fullscreen and ~960x720 or ~640x480 resolution with XV UI, so all measures made on maximized window (1400x1050).

We can see: SDL2 UI overperform the SDL UI with 50%-60%, and with an easy scaler even surpasses the GTK UI.

With SDL2s 'virtual resolution' we can easily implement a resizeable main window. So, now users can freely resize the main window. If SDL2 run over X11, fuse can use X11/Xutils WMSizeHints to force main window aspect ratio during resizing. (I don't know about similar feature for Windows or other underlying subsytem...??)
If SDL run on other WM or we disable this feature at configuration time (--disable-wm-aspect), fuse try to keep aspect ratio with adjusting the window size after user resize event.


Changes:
* Makefile.am:
- add SDL2 LIBS
* configure.ac:
- add SDL2 detection
--with-sdl: first try SDL2 next SDL1
--with-sdl=1: force use of SDL1
--disable-wm-aspect: disable using WM aspect (size) hints with X11 subsytem
* keysyms.{dat,pl}, input.h:
- add some new key symbol to SDL1/2 UI can use more ASCII char in widgets (e.g. underscore, braces, tilde, at...)
* sound/Makefile.am:
- add SDL2 LIBS
* timer/Makefile.am:
- add SDL2 LIBS
* ui/options.dat:
- add fulscreen option for SDL2 UI
* widget/widget.c:
- make 'ui_statusbar_...' functions work from SDL2 UI
* sdl/Makefile.am:
- add SDL2 LIBS
* sdl/sdl2display.h
- add some #define to eliminate the difference between SDL2/SDL1 keycodes (SDLK_...)
* sdl/display.h
- add externs for SDL2
* sdl/sdl2display.c
- new file to implement SDL2 rendering logic. The main difference is SDL2 uses windows, renderers and textures instead of surfaces. The SDL2 UI uses SDL2 renderer virtual size, so very easy to implement rescalable main window. Note: all other files used both (SDL1/SDL2) UI with #ifdefs.
* sdl/sdlui.c:
- SDL2 uses WINDOW events instead of VIDEOEXPOSE, TEXTINPUT for unicode keyboard input, SetWindowTitle instead of WM_SetCaption, SetRelativeMouseMode for grab/ungrab mouse, etc..
- implement poor man's aspect ratio handling, if there is no X11 subsytem (or disabled)
* sdl/sdlkeyboard.{h,c}
- new function to handle SDL2 TEXTINPUT
- we use TEXTINPUT only for widget system
* sdl/sdljoystick.c
- add UI_SDL2 #ifdefs

1 Attachments

Related

Patches: #216
Patches: #405
Wiki: Fuse 1.2 Release Plan
Wiki: Fuse 1.2.2 Release Plan
Wiki: Fuse 1.3.0 Release Plan
Wiki: Fuse 1.3.1 Release Plan
Wiki: Fuse 1.3.2 Release Plan
Wiki: Fuse 1.3.3 Plan
Wiki: Fuse 1.3.4 Release Plan
Wiki: Fuse 1.3.5 Release Plan
Wiki: Fuse 1.3.6 Release Plan
Wiki: Fuse 1.3.7 Release Plan
Wiki: Fuse 1.3.8 Release Plan
Wiki: Fuse 1.4.0 Release Plan
Wiki: Fuse 1.4.1 Release Plan
Wiki: Fuse 1.5.0 Release Plan
Wiki: Fuse 1.5.1 Release Plan
Wiki: Fuse 1.5.2 Release Plan
Wiki: Fuse 1.5.3 Release Plan
Wiki: Fuse 1.5.4 Release Plan
Wiki: Fuse 1.5.5 Release Plan
Wiki: Fuse 1.5.6 Release Plan
Wiki: Fuse 1.5.7 Release Plan
Wiki: Fuse 1.6.0 Release Plan
Wiki: Fuse Next Release Plan

Discussion

<< < 1 2 (Page 2 of 2)
  • Gergely Szasz

    Gergely Szasz - 2015-01-05

    I test the performance again:

    with "always full screen refresh" (OPIUM4K demo)
    SDL2 overperform SDL1 about 3x

    with other case SDL1 overperfom SDL2.

    I test it with Pyjamarama, because it has a "demo". I modified the sdlui.c to print every speed update to stderr, so I collect 410 sample (skipped the first 10)

    ./fuse ../demo/pyjama.tzx -m 128 -g 3x --speed 9000 2>speed.txt

    I create a second SDL2, when fuse at every frame end detect: SDL use an "integer" (e.g.: 1.0, 2.0 ...) or not integer (e.g. 1.123) scaling factor. If scaling factor is integer, then copy every rectangle, if not copy the whole screen.

    Average speed:
    SDL1: 5069%
    SDL2: 3374%
    SDL2(integer): 3470%

    So with that case SDL1 overperform SDL2 about 1.5x

     
  • Sergio Baldoví

    Sergio Baldoví - 2015-01-06

    with "always full screen refresh" (OPIUM4K demo) SDL2 overperform SDL1 about 3x

    Interesting. The dirty region drawing and the limit of 300 rects was set for SDL1 so might not be useful for SDL2.

    The SDL2 wiki states that SDL_UpdateTexture is a fairly slow function. Hence reducing the number of updates at the expense of using bigger areas might improve the performance.

    I create a second SDL2, when fuse at every frame end detect: SDL use an "integer" (e.g.: 1.0, 2.0 ...) or not integer (e.g. 1.123) scaling factor. If scaling factor is integer, then copy every rectangle, if not copy the whole screen.

    So the specific code for "integer" scaling improves a 3%? It seems that the gain does not worth the code complexity.

    For my tests I've used a similar measuring technique with RZXs, based on a previous benchmark for Windows:
    https://sites.google.com/site/serbalgi/gdirenderer

    I take care all window area is visible because the drawing is faster when the window is clipped by the desktop. I avoid the shock demo as tends to do a core dump when played at high speed.

     
  • Gergely Szasz

    Gergely Szasz - 2015-02-05

    I created a little benchmark with:
    Chaos
    ChaseHQ
    DanDare
    DarkScept
    Elite
    Flyingshark
    HeadOverHeels
    ManicMiner
    Pyjamarama
    Quazatron
    Turbo
    Uridium
    The test measures the speed of emulation at different maximum number of rectangles (MAX_UPDATE_RECT). The test run from 5 to 495 with step 5. At every value I measured the speed 3x, and summ up it. Every test run 16384 frames long.
    I made a reference test for all game with use only one "big" rectangle for texture upload per a frame (curves marked with 1 on the second chart).

    The test show that:
    - the "partial update" method more efficiet than the "one texture upload per frame"
    - the MAX_UPDATE_RECT should bigger than 225, so 300 is optimal for SDL2 too
    - SDL2 UI slower in most cases than the SDL1 (but when fuse need to update the whole speccy screen at every frame)
    - may we make a test with oldschool surface blitting...

    I attached the patch, the raw data file, the script and two png.

     

    Last edit: Gergely Szasz 2015-02-05
  • Sergio Baldoví

    Sergio Baldoví - 2015-03-04

    the "partial update" method more efficiet than the "one texture upload per frame"

    I think your "one texture upload per frame" method is not optimised. You are feeding the 3x scaler with more data that have changed. It would be better to scale N rectangles in the backbuffer and then upload the whole texture in one piece (see attachment).

    After a quick look, I see the "one texture" method faster with 1x frame size and similar to 300-rect with 3x frame size. No idea how performance will behave when a 1x frame is scaled to 3x in GPU (without the need of a fixed scaler).

    SDL2 UI slower in most cases than the SDL1 (but when fuse need to update the whole speccy screen at every frame)
    may we make a test with oldschool surface blitting...

    Probably SDL_UpdateWindowSurfaceRects will be faster, but that leaves out the freely resizeable windows. I suspect SDL1 UI will never be deprecated because SDL2 has not been ported to many platforms so we might target SDL1 UI to low powered devices and SDL2 UI to desktops with hardware acceleration.

     
  • Alberto Garcia

    Alberto Garcia - 2023-06-19

    Hi, what's the status of SDL2 support in Fuse ?

    SDL1 is going to be removed from e.g. Debian and the only alternative would be to use sdl12-compat (which seems to work fine btw) https://github.com/libsdl-org/sdl12-compat

     
<< < 1 2 (Page 2 of 2)

Log in to post a comment.