GLBasic forum

Main forum => GLBasic - en => Topic started by: S.O.P.M. on 2014-Sep-06

Title: Bottleneck of my current project
Post by: S.O.P.M. on 2014-Sep-06


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...
Title: Re: Bottleneck of my current project
Post by: S.O.P.M. on 2014-Sep-06
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?
Title: Re: Bottleneck of my current project
Post by: fuzzy70 on 2014-Sep-06
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
Title: Re: Bottleneck of my current project
Post by: erico on 2014-Sep-06
Virtual screens are working fine on android, you should be fine.
Title: Re: Bottleneck of my current project
Post by: spacefractal on 2014-Sep-06
Also DRAWRECT Might not been colored on some devices. Use POLYVECTORS and do fewer calls.
Title: Re: Bottleneck of my current project
Post by: Hemlos on 2014-Sep-07
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

Title: Re: Bottleneck of my current project
Post by: S.O.P.M. on 2014-Sep-07
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.
Title: Re: Bottleneck of my current project
Post by: spacefractal on 2014-Sep-07
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.
Title: Re: Bottleneck of my current project
Post by: S.O.P.M. on 2014-Sep-07
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?
Title: Re: Bottleneck of my current project
Post by: erico on 2014-Sep-07
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...
Title: Re: Bottleneck of my current project
Post by: fuzzy70 on 2014-Sep-07
I just tested the simple program I posted on different topic http://www.glbasic.com/forum/index.php?topic=9975.msg87568#msg87568 (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
Title: Re: Bottleneck of my current project
Post by: Hemlos on 2014-Sep-07
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
Title: Re: Bottleneck of my current project
Post by: Qedo on 2014-Sep-07
GRABSPRITE  on ANDROID devices doesnt work . Use CREATESCREEN and USESCREEN

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

Ciao
Title: Re: Bottleneck of my current project
Post by: Hemlos on 2014-Sep-07
gonna say...i had no fix...it was a problem with setting SETTRASPARENCY, which i removed.
Title: Re: Bottleneck of my current project
Post by: S.O.P.M. on 2014-Sep-07
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.
Title: Re: Bottleneck of my current project
Post by: S.O.P.M. on 2014-Sep-07
Have to say sorry, my understanding for mathematics is quite limited so programming can easily become a running the gauntlet for me. Finally I found the right formula and my checkerboard background can be drawn correctly:

Code (glbasic) Select

FOR i = 0 TO 16 STEP 16
    FOR j = 0 TO 16 STEP 16
        FOR k = 0 TO 7
            FOR l = 0 TO 7
                Ima[(i * 32) + j + (k * 32) + l] = 0xFF444444
                Ima[(i * 32) + 8 + j + (k * 32) + l] = 0xFF323232
                Ima[256 + (i * 32) + j + (k * 32) + l] = 0xFF323232
                Ima[256 + (i * 32) + 8 + j + (k * 32) + l] = 0xFF444444
            NEXT
        NEXT
    NEXT
NEXT


But one thing I noticed though. Normally the color value 0x222222 that I used is clearly visible. In this case, if I set it as 0xFF222222 for MEM2SPRITE I got black pixels. Why?

[EDIT]

Fortunately this method works on Android nice and smooth, so it's an acceptable solution for me, even if a bit unlikely. Please pardon the inconvenience!
Title: Re: Bottleneck of my current project
Post by: Hemlos on 2014-Sep-08
0xFF222222

try 0xFF2222 instead

Hex is basically 6 characters long not 8 (not including the 0x part of course)

R G B red green blue  each is 2 chars long

This color should look pink.
Title: Re: Bottleneck of my current project
Post by: fuzzy70 on 2014-Sep-08
Quote from: Hemlos on 2014-Sep-08
0xFF222222

try 0xFF2222 instead

Hex is basically 6 characters long not 8 (not including the 0x part of course)

R G B red green blue  each is 2 chars long

This color should look pink.
MEM2SPRITE colours in array are 8 chars(32bit), 2x each of Alpha, Blue, Green, Red. 0xAABBGGRR.

I should be home soon so will have a look at your code more closely S.O.P.M when there. Also 0xFF222222 is a very very dark gray. Does it look black on windows or android as don't forget nearly all android devices are 16bit colour & not 24bit like pc's etc.

Lee
Title: Re: Bottleneck of my current project
Post by: Hemlos on 2014-Sep-08
hmm
Title: Re: Bottleneck of my current project
Post by: S.O.P.M. on 2014-Sep-08
Quote from: fuzzy70Also 0xFF222222 is a very very dark gray. Does it look black on windows or android as don't forget nearly all android devices are 16bit colour & not 24bit like pc's etc.
Yes, it's a quite dark gray but it was cleary visible on a black ground under Win and also on my Android phone. I still believe 0xFF222222 should be exactly the same color value than without the transparency declaration 0x222222. So I don't understand why DRAWRECT x, y, w, h, 0x222222 is visible and 0xFF222222 if saved for MEM2SPRITE absolutely not.

However, this is not a problem because I was able to get a similar grey with other values. And that's all I need. Would still nice to understand the mathematical or other background, though.
Title: Re: Bottleneck of my current project
Post by: fuzzy70 on 2014-Sep-08
Interesting, I just done a test with the following code
Code (glbasic) Select
LOCAL spritemem%[]
LOCAL loop%

DIM spritemem[76800]

FOR loop = 0 TO 76799
spritemem[loop]=0xFF222222
NEXT

MEM2SPRITE(spritemem[],1,320,240)
DRAWSPRITE 1,321,0

DRAWRECT 0,0,320,240,0x222222

SHOWSCREEN

MOUSEWAIT

which basically draws 2 rects the same colour, 1 using DRAWRECT & other with a sprite made from MEM2SPRITE & the result was as expected, 2 rects the same colour.

Tested on both Windows & Android.

Lee
Title: Re: Bottleneck of my current project
Post by: S.O.P.M. on 2014-Sep-08
Impossible... your code is working. Now I've changed my code again and it works also. Don't ask me what was wrong the last time.

Another thing puzzles me now. The CPU load is very different in same situations. One time I start the program it goes not above 10%, another time it's at 20-25% permanently. Sometimes the load reduces by itself while the app is running and nothing else changes. I can minimize the window and if I bring it back the load can be very low while I can use the app on any screen. How can that be? My graphics driver is up to date.
Title: Re: Bottleneck of my current project
Post by: fuzzy70 on 2014-Sep-08
Welcome to windows lol. No seriously though I have that problem with non glb apps as well & never really got to the bottom of it.

Lee
Title: Re: Bottleneck of my current project
Post by: S.O.P.M. on 2014-Sep-08
I don't think it's windows. Not that I observed the overall load, no, the load of exactly my app. I'm sure it's an issue with OpenGL.
Title: Re: Bottleneck of my current project
Post by: MrPlow on 2014-Oct-15
You can significantly reduce all draw calls by drawing 1 large rect of black then draw white tiles using a step in you loop calculations

You dont need to draw all 64 squares - Just 17
:P
Title: Re: Bottleneck of my current project
Post by: MrPlow on 2014-Oct-15
duplicate...
Title: Re: Bottleneck of my current project
Post by: S.O.P.M. on 2014-Oct-19
Luckily, all problems are gone. The app currently runs perfectly fine, even if there's a lot to do before it's finished. Programming is always a great learning experience for me.