[Compatibility] Allow Monitor to take care of their own texture
Closed this issue · 4 comments
lamogui commented
In ADDITION of providing sf:Image, i think we can add a sf::Texture to avoid texture.loadFromImage or If in the futur we need it.
- The AbstractMonitor should have a use_texture flags that enable this.
- The monitor should only recreate the texture only while it necessary (switch emulation/videos modes)
- The monitor should update the texture using texture.update(screen) once by render (at the end)
Somes other ideas
- Replace sf::Image* with sf::Image& (because the sf::Image is no more dynamically allocated)
- Replace sf::Image* with uint8_t* pointer better compatibility and speed (no slow setPixel function but need to rewrite cgm render)
I wait for discussions...
Zardoz89 commented
Copy&paste form the closed issue:
- I think that we must avoid call updateScreen() in tick(). It's a slow process that can slowdown the VM. Instead, call be called from getScreen() when this function detects that the video ram has changed. To detect this, we can simply run a checksum (or a fast hash) routine in the video ram every 2000 CPU ticks. If the checksum has changed, before the previous flag, then the video ram has changed. A checksum it's much more faster that updating the whole screen.
I think that a objetive should move out any sfml dependet code outside of the hardware device code, so we could do this :
- We should change to use an array of uint8_t[width_height_4] to store pixel data in RGBA format. And give read access to it from outside (getScreen())
- By the same reason, getBorder() should return a uint8_t[4] storing the boder color in RGBA format.
lamogui commented
- for uint8_t* screen, i think it's better to have an dynamic allocation cause the lem1803 screen have not the same size than the lem1802 so AbstractMonitor should provide a virtual allocateScreen() function.
- for the checksum it can be cool but it must be very fast and used in updateScreen after need_render and after the render itself
- call updateScreen when getScreen is called is not a good idea -> wrong refresh (for instance if the DCPU program refresh the video ram in the same time). calling it tick is better for that reason. need_render prevent the slow render process if a game engine doesn't need to render the screen it just not call prepareRender... + getScreen is more like an accessors which provide an access to a member. Finaly it doesn't solve the problem it's just move it.
Zardoz89 commented
A typical checksum it's O(N) with a very fast internal operation. In pseudo-code:
uint16_t checksum = 0
for (i=0 to video_ram_size)
checksum = (checksum + videoram[i]) & 0xFFFF;
return checksum
Not have the same reliability that a hash function but can do the job enough well for this.
Zardoz89 commented
I will close this for the moment. We can open a new issue if we need to discuss about how make more efficient the monitor code.