dchapiesky wrote:
disregard my previous post....
ok.... here are some questions...
in:
https://github.com/madd-games/glidix/bl ... /src/ptr.cYou spawn a separate thread to draw the mouse as it moves where:
ptrThreadFunc loops on a read() and then calls wndMouseMove which calls wndDrawScreen
1) is your OS blocking on read()? or is the <0 saying nothing was available so loop again?
2) why not use select() or poll() if your OS implements them?
I ask because it looks like your mouse thread beats the hell out of the CPU and thrashes the cache.
The read() is blocking. The "<0" check just ensures that there was no error in the read.
dchapiesky wrote:
in:
https://github.com/madd-games/glidix/bl ... c/window.cin wndMouseMove() you lock mouseLock, unlock mouseLock, and then call wndDrawScreen() which locks mouseLock and unlocks mouseLock
in wndMouseMove() you lock wincacheLock, unlock wincacheLock, and then call wndDrawScreen() which locks wincacheLock and unlocks wincacheLock
3) could you create merge wndDrawScreen into wndMouseMove to get rid of the redundant locks?
4a) in fact you have a ton of locks... like the desktop lock.... not sure why the desktop has to be locked to draw a mouse sprite....
4b) so many locks that I can't help but think many of them are being used where they are not necessarily required or redundant
-mouseLock synchronizes access to the global mouse position variables (mouseX, mouseY).
-wincacheLock synchronizes access to the "window cache"; which remembers the currently "hovered" window (the window that the mouse currently points at), the window in focus, and the "active" window (currently clicked).
-the "desktop lock" is just the lock for the desktop window, so a special case of the window lock. Furthermore, it synchronizes access to the framebuffer, and wndDrawScreen() draws everything (i.e. the contents of the desktop window's display) plus the mouse cursor.
-the window lock obviously synchroniizes access to an individual Window structure. Each window has its own lock and a reference counting is used so that the parent's lock does not need to be held when modifying most properties of its child.
In general, you should see that all locks are held for a very short time. (If you see that they are not, you can point that out to me).
wndMouseMove() and wndDrawScreen() aren't merged because they do separate things, and wndDrawScreen() is called from other parts of the code. wndMouseMove() reports mouse motion and then calls wndDrawScreen(), which just draws the desktop window and cursor on top.
dchapiesky wrote:
5) you call ddiOverlay() which passes a ton of args to a function which is linked from the libddi library - unless you have link time optimizations then this function should be in a header for inlining - just to get rid of the function call...
6) you use stock memcpy() and memset() alot.... since this is a x86_64 OS perhaps using SSE or even AVX versions of these functions will help... certainly a 128 bit memcpy could help.... here is an MIT licensed set of examples.... seriously good read:
https://github.com/skywind3000/BasicBit ... p_SSE2.cpp There is probably more issues - but the locks and memcpy and the mouse thread hammering the CPU are the worst offenders.... (in that order if your read() function blocks)
I want to thank you though... your code is SUPER EASY to understand and very well written.
Cheers
ddiOverlay() is an optimised memcpy() essentially, it copies a surface onto another without alpha blending etc. As stated before, ddiBlit() (which DOES do alpha blending) can perform 3000 operations on 500x500 surfaces in one second; so ddiOverlay() does at least as much.
Inlining ddiOverlay() would probably be a bad idea since libddi is supposed to, some day, support hardware acceleration.