Bottleneck of my current project

Previous topic - Next topic

S.O.P.M.



Hello, please watch this short demonstration. This is my current project. For several reasons I've written my own window- and gadget-management that fits my purposes perfectly. The game itself is already there but I've to rebuild the user interface with a new level editor. Design comes later. Anyway, I've no clue at the moment, why everything is running so slowly, the old application reached 60 fps on Android easily.

The window management works as follows. Windows are defined via functions and stored in arrayed types. Then there's a window list to define the order all opened windows will be displayed. Only windows that can be visible will be drawn so for performance reasons it's basically not necessary to close each window when a new one is completely in front of the other. There can be subs that are appended to each window and will be called via the CALLBYNAME command.

Is it known that this command causes trouble under Android? At least I've never used it before.

Also each window has it's own gadget list that tells the window drawing routine which gadgets has to be drawn within a window. And there's a buffer for a window background- and foreground drawing routine. Gadgets will drawn between. Finally each window has a function list that contains all functions that are executed before everything will be drawn. These functions can be triggered by changing window state slots.

Unfortunately I cannot show you the full source code because the project shall go a little beyond the hobby state, let's say.

Any suggestions what could cause the speed issue? Note the sudden speed gain when the world overview window is opened. And I can tell you for sure, all other windows are still there...
Notebook PC Samsung E372 Core i5 @ 2,6 GHz; 4 GB RAM; Win 7 Home Premium

S.O.P.M.

#1
Ok guys, I found the issue. It's the sub that draws the chessboard background! Under Win32 I checked the CPU load while running the application and the window with that background caused around 40% cpu load. By removing that drawing function I saved 30% load! This is the function:

Code (glbasic) Select
SUB ChessBoard:
LOCAL x%, y%
x = GetWindowXPosition(1)
y = GetWindowYPosition(1)
FOR i = 0 TO BasScrHei / 16
FOR j = 0 TO BasScrWid / 16
DRAWRECT x + 0 + j * 16, y + 0 + i * 16, 8, 8, 0x444444
DRAWRECT x + 8 + j * 16, y + 8 + i * 16, 8, 8, 0x444444
NEXT
NEXT
ENDSUB


BasScrHei = 512 and BasScrWid = 1024 so we have 64 x 32 x 2 = 4096 DRAWRECT calls. Each rect with a size of 8 x 8 pixels. I was not expecting this to cause so much ressources...
What do you think, is this usual?
Now how about a good workaround? To host this repetitive 1024 x 512 pixel background as a graphic file would be very unprofessional. I would like to draw it once and then save it during run time. Hopefully GRABSPRITE will work... or how would you do that?
Notebook PC Samsung E372 Core i5 @ 2,6 GHz; 4 GB RAM; Win 7 Home Premium

fuzzy70

There are numerous ways to draw checkerboards, personally I would create a 64x32 checkerboard sprite then draw a single POLYVECTOR with SMOOTHSHADING set to false the size of the screen. The sprite could be generated at runtime or at the start if you are planning different resolutions, however I'm not 100% sure if virtual screens are currently working on Andriod.

Lee
"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)

erico

Virtual screens are working fine on android, you should be fine.

spacefractal

Also DRAWRECT Might not been colored on some devices. Use POLYVECTORS and do fewer calls.
Genius.Greedy Mouse - Karma Miwa - Spot Race - CatchOut - PowerUp Elevation - The beagle Jam - Cave Heroes 2023 - https://spacefractal.itch.io/

Hemlos

#5
Try precalculating the math before hitting loops.

LOCAL LOOPENDVAL% = BasScrHei / 16

Also precalculate the Draw requirements.

LOCAL DX% = x + 0 + j * 16
LOCAL DY% = y + 0 + i * 16

The problem is you are doing 16 * 16 * 6 calculations everytime you hit that sub.
You need to reduce the cpu workload here.


You can also reduce compile time by organizing the math a little bit..
LOCAL DX% = (j * 16) + x


I dont know if it will be noticable or not...but i assume on a small machine you might..try replacing the routine with this:

Code (glbasic) Select


SUB ChessBoard:
        LOCAL x% = GetWindowXPosition(1)
        LOCAL y% = GetWindowYPosition(1)
        LOCAL H2% = BasScrHei / 16
        LOCAL W2% =  BasScrWid / 16
        FOR i = 0 TO H2
                LOCAL Y2 = (i * 16) + y
                LOCAL Y3 = (i * 16) + y + 8
                FOR j = 0 TO W2
                    LOCAL X2 = (j * 16) + x
                    LOCAL X3 = (j * 16) + x + 8
                    DRAWRECT X2, Y2, 8, 8, 0x444444
                    DRAWRECT X3, Y3, 8, 8, 0x444444
                NEXT
        NEXT
ENDSUB

Bing ChatGpt is pretty smart :O

S.O.P.M.

Great hints! Thanks a lot. Had really not such ideas before even if it sounds quite plausible once adverted :)

Will test it out and give feedback about the results. I confirm, virtual screens are working fine on Android, my application uses it to fit on all resolutions.
Notebook PC Samsung E372 Core i5 @ 2,6 GHz; 4 GB RAM; Win 7 Home Premium

spacefractal

Just to mention, it's does do have some sort of speed penaty using virtual screen, but again it's depend on project.

None of my projects use them.
Genius.Greedy Mouse - Karma Miwa - Spot Race - CatchOut - PowerUp Elevation - The beagle Jam - Cave Heroes 2023 - https://spacefractal.itch.io/

S.O.P.M.

#8
Yes, that's no question. But it's absolutely necessary. Every good app you want to offer should handle different screen resolutions. And I honestly can't imagine that any other scaling technology than the one using virtual screens is as efficient and easy to use for the programmer. But please put it right if you know the truth ;)

Ok, the new results are somewhat disappointing. I tried to reduce the realtime mathematics and was able to notice a small difference. A little bit more speed but still much too slow. Then I tried to draw the same checkerboard by using POLYVECTOR. No difference, almost same load.

Then I was happy to find this method:

Code (glbasic) Select
SUB ChessBoard:
STATIC ini%
LOCAL x%, y%
x = GetWindowXPosition(1)
y = GetWindowYPosition(1)
IF ini = 0
ini = 1
DRAWRECT 0, 0, BasScrWid, BasScrHei, 0x222222
FOR i = 0 TO BasScrHei STEP 16
FOR j = 0 TO BasScrWid STEP 16
DRAWRECT 0 + j, 0 + i, 8, 8, 0x444444
DRAWRECT 8 + j, 8 + i, 8, 8, 0x444444
NEXT
NEXT
GRABSPRITE 1, 0, 0, BasScrWid, BasScrHei
ELSE
DRAWSPRITE 1, x, y
ENDIF
ENDSUB


It works pretty nice under Win32, got similar low load as on other screens/windows. But then the disappointment when running on Android: The grabbed sprite is completely white. So I assume GRABSPRITE isn't working properly on Android, currently. Or is there something that I've missed?
Notebook PC Samsung E372 Core i5 @ 2,6 GHz; 4 GB RAM; Win 7 Home Premium

erico

What android device are you using as a base test?
I wonder why not do the board with drawsprite of a white and a black square? I could be missing something here...

fuzzy70

I just tested the simple program I posted on different topic http://www.glbasic.com/forum/index.php?topic=9975.msg87568#msg87568 & the grabsprite fails on my android phone, Xperia Z running 4.4.2.

Rest of the program runs as expected but it drawn sprite is empty/blank.

Lee
"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)

Hemlos

hmm i had an issue with grabsprites in AGOSA on win32..
...ill look into it and see what i came up with as the solution, bbiab
Bing ChatGpt is pretty smart :O

Qedo

GRABSPRITE  on ANDROID devices doesnt work . Use CREATESCREEN and USESCREEN

http://www.glbasic.com/forum/index.php?topic=8217.msg69305#msg69305

Ciao

Hemlos

gonna say...i had no fix...it was a problem with setting SETTRASPARENCY, which i removed.
Bing ChatGpt is pretty smart :O

S.O.P.M.

#14
Oh...

Now I try the MEM2SPRITE method and have much trouble to get the formula right to bring a set of the checkerboard pattern into the data matrix. I thought to make 32x32 pixel sprites from it so I've to create a set of 4x4 of these 8x8 pixel squares. This is the current function:

Code (glbasic) Select
SUB ChessBoard:
STATIC ini%
LOCAL Ima%[]
LOCAL x%, y%
x = GetWindowXPosition(1)
y = GetWindowYPosition(1)
IF ini = 0
ini = 1
REDIM Ima[1024]
FOR i = 0 TO 31 STEP 16
FOR j = 0 TO 31 STEP 16
FOR k = 0 TO 7
FOR l = 0 TO 7
Ima[(i * 32) + j + (k * 32) + l] = 0xFF444444
NEXT
NEXT
NEXT
NEXT
MEM2SPRITE(Ima[], 1, 32, 32)
DIM Ima[0]
ENDIF
FOR i = 0 TO BasScrHei STEP 32
FOR j = 0 TO BasScrWid STEP 32
DRAWSPRITE 1, x + j, y + i
NEXT
NEXT
ENDSUB


The result you can see in the screenshot. So far all right. I've marked the pattern set this function creates. Now I've to place another 3 squares right from, below and diagonal right/below of the first one. But no matter how I change the formula
Code (glbasic) Select
(i * 32) + j + (k * 32) + l the result is absolutely wrong. To my understanding the formula to place one more square right of in the matrix should be
Code (glbasic) Select
(i * 32) + j + 16 + (k * 32) + l but it isn't.
Notebook PC Samsung E372 Core i5 @ 2,6 GHz; 4 GB RAM; Win 7 Home Premium