rtoumazet / saturnin

Saturnin is a Sega Saturn emulator
Apache License 2.0
2 stars 0 forks source link

VDP2 render timing problem #246

Closed rtoumazet closed 2 years ago

rtoumazet commented 2 years ago

While displaying the "set time" screen, moving the cursor (displayed by the VDP1) doesn't move the yellow arrows (displayed by the VDP2). The date numbers aren't updated also, you need to click the "Reload cache" button to get the correct display.

It's actually a synchronization problem between the UI thread and the emu thread.

rtoumazet commented 2 years ago

Actually the problem is elsewhere : rendering is done through OpenGL for both the Saturn and Imgui. Imgui UI displays one frame every 1/60s (16.67ms). During that time, Saturn image calculation and rendering must be done too. If rendering is too long, the Saturn frame data is dropped and a new frame is started. In that case rendering is always cut before being complete, leading to a partly rendered screen, or even to a black screen. What needs to be done is to keep Saturn data when it takes longer to display than a Imgui frame, and to display it when complete during the next Imgui frame.

rtoumazet commented 2 years ago
Current implementation : UI thread Rendering thread
opengl()->isThereSomethingToRender() opengl()->displayFramebuffer() called from vdp2->run()
opengl()->generateTextures()
opengl()->render() (uses parts_listmutex)

Mutexes declared in opengl.h

rtoumazet commented 2 years ago

Tasks from the UI thread :

Tasks from the emulation thread

rtoumazet commented 2 years ago

Concurrent access listing

Location Variable Function UI thread Emu thread Mutex
Texture texturestorage storeTexture() none W X
Texture texturestorage getTexture() R R X
Texture texturestorage isTextureLoadingNeeded() none R/W X
Texture texturestorage discardCache() R/W R/W X
Texture texturestorage setCache() none R/W X
Texture texturestorage cleanCache() none R/W X
Opengl partslist displayFramebuffer() none W X
Opengl partslist render() W none X
Opengl texture_key_idlink isThereSomethingToRender() W none
Opengl texture_key_idlink addOrUpdateTexture() none R/W
Opengl texture_key_idlink generateTextures() R/W none
Opengl textures_todelete isThereSomethingToRender() W none
Opengl textures_todelete addOrUpdateTexture() none R/W
Opengl textures_todelete generateTextures() R none
rtoumazet commented 2 years ago

Saturn textures

Stored into a texture pool in Texture.h. Each texture contains raw data, and is called from OpenGL to generate OpenGL textures to be used while rendering.

OpenGL textures

Created in generateTextures(), where unused OpenGL textures are first deleted, then generated if needed.

rtoumazet commented 2 years ago

UI thread (ie data processing) :

Emu thread (ie data preparation) :

rtoumazet commented 2 years ago

Synchronization issue is fixed, but rendering is now slower. Time to investigate what can be done to improve this.