Ahmed Khalifa Posted August 22, 2018 Share Posted August 22, 2018 I am working on a project that uses exactly 1 group, couple of containers (around 30) containing a picture from a tiny texture and a text, and 2 graphics object. When I select Phaser.WEBGL (Phaser.AUTO also selects WebGL), the game slows down after one minute or something. The game frame rate drop to almost 5 fps. I though there is something wrong with my code at the beginning and tried to optimize calling functions and other parts but with no affect on the final result. When I changed to Phaser.CANVAS, the game is very fast and maintaining 60 fps. I don't know if that is a bug in the framework or misuse in my code. I am testing on chrome browser on a Mac Book from 2015. here is a link of the game using canvas: http://akhalifa.com/testing/reduce/canvas/ here is a link of the game using webgl: http://akhalifa.com/testing/reduce/webgl/ Link to comment Share on other sites More sharing options...
rich Posted August 23, 2018 Share Posted August 23, 2018 I profiled the WebGL version for 30 seconds and in that time it spent 1631ms scripting, 124ms rendering, 225ms painting and the remaining time doing nothing. In order words, it was 91% idle. Which sounds about right for a relatively simple game like this. The game uses a number of Text objects, so it'd be well worth swapping to use bitmap text, as each Text object causes a batch flush in WebGL. Also, make sure your Graphics objects aren't being re-drawn to each frame (i.e. if you draw something new to them, clear them first, then draw, otherwise they build up and up over time, causing loads of memory - I didn't see this in my profile though, so I don't think you're doing it) Check you don't have any Chrome extensions installed that may be getting in the way? And profile it for yourself to see where the time is being spent. Link to comment Share on other sites More sharing options...
Ahmed Khalifa Posted August 23, 2018 Author Share Posted August 23, 2018 Thanks Rich, I will definitely try using bitmap fonts but shouldn't it slow down that much even if I am using around 30 normal font objects? It is weird that it didn't slow with time with you. Did you start profiling after the game started (after loading)? As the loading take long time and the game start to slow down after it start by a minute or something. May be it slows down when u play in it, try to remove letters to have a correct English word. I will test the bitmap font and see although I just wanted to use normal font. Also is updating Phaser.GameObject.Text text is it intensive from GPU point of view (as I change two text objects every frame)? Link to comment Share on other sites More sharing options...
Ahmed Khalifa Posted August 23, 2018 Author Share Posted August 23, 2018 I just tried using Bitmap fonts and no difference same weird problem. And I found out that tint is not working in canvas (all bitmap text are white). Just play the game for a minute in webgl and you will see the slow down (remove letters from the sequence to get a correct english word), tried different computers and same problem happens at all of them. I even restarted the computer. Link to comment Share on other sites More sharing options...
rich Posted August 23, 2018 Share Posted August 23, 2018 Tint is WebGL only. I didn't play the game at all, I just let it run in the profiler (I started profiling after loading, not before) and didn't see any slow down on my Mac or PC, but this could easily be something else GPU / driver / extension related. You need to profile it and see what's causing the lag. Link to comment Share on other sites More sharing options...
Ahmed Khalifa Posted August 23, 2018 Author Share Posted August 23, 2018 I just did profiling I don't know if these values are normal or not. 4430.4 ms Scripting 346.1 ms Rendering 658.5 ms Painting 3473.6 ms Other 64904.0 ms Idle The average frame rate is 15 frames Getting the tree call, I can see the rendering consume most of the time. Attached a picture of the call tree. Link to comment Share on other sites More sharing options...
Ahmed Khalifa Posted August 23, 2018 Author Share Posted August 23, 2018 Also I don't think, it is problem of driver as I tested it on multiple different devices and they all have the same behavior. Also will Canvas at some point support Tint? Link to comment Share on other sites More sharing options...
rich Posted August 23, 2018 Share Posted August 23, 2018 3ms spent on rendering per frame is absolutely fine. Here's 30 seconds of me "playing" (I've no idea what you do in the game, so all I did was randomly click the letters) A lot of script processing going on, but very little else. The Chrome FPS meter stays at solid 60fps, never dropping a single frame until the progress meter (or whatever it is? a timer bar?) starts to get really small. For about the final 20 seconds before it runs out the FPS drops down lower and lower, ending around 40fps for me. As soon as the timer bar resets to full again it shoots right back up to 60fps and remains there until it gets small again. Clicking the letters seems to make no difference to this, it just appears to be when the timer bar gets tiny. Isolate whatever you're doing with that bar, as I reckon it's the cause. There are no plans to add tint support for Canvas, no. Link to comment Share on other sites More sharing options...
Ahmed Khalifa Posted August 23, 2018 Author Share Posted August 23, 2018 Thanks, It is scaling a graphics object (not a bitmap) down. Is there a problem with that? I don't redraw the object at all (I draw it one time at create only) Link to comment Share on other sites More sharing options...
rich Posted August 23, 2018 Share Posted August 23, 2018 Isolate it and see. If it's just a Graphics fillRect you should clear and redraw the rect, not scale it. Link to comment Share on other sites More sharing options...
rich Posted August 23, 2018 Share Posted August 23, 2018 Solid 60fps here (as I'd expect to be honest, it's hardly doing much): var config = { width: 800, height: 600, type: Phaser.WEBGL, parent: 'phaser-example', scene: { create: create } }; var game = new Phaser.Game(config); function create () { var graphics = this.add.graphics(); graphics.fillStyle(0x00ff00, 1); graphics.fillRect(0, 300, 800, 64); this.tweens.add({ targets: graphics, scaleX: 0, duration: 20000, ease: 'Linear', repeat: -1 }); } Maybe something else is going on in the game code when the timer gets small? Link to comment Share on other sites More sharing options...
Ahmed Khalifa Posted August 23, 2018 Author Share Posted August 23, 2018 That's weird because nothing different since the beginning. So I start to try to corner the problem and I think I found it. So the background is 1x1 pixel that is scaled to cover the whole screen. Every frame, I redraw it using the correct color (green or red) without calling clear based on the current status in the map. When I commented this part, everything become very fast. So I added the clear in and everything is still fast. Is the graphics object keep track with all the previous drawings and recall all the drawing calls for every render? If that is the case, it make sense that it slows down near the end as it accumulated a lot of fillRect calls since the beginning of the game. I thought without calling clear, it just redraw the object on a texture on the previous drawings and use it. Link to comment Share on other sites More sharing options...
rich Posted August 23, 2018 Share Posted August 23, 2018 Graphics objects work using a command stack. So if you create a Graphics object, then draw a rectangle to it every frame without clearing it, after 1 second you'll have 60 rectangles, after 2 seconds 120 rectangles, and so on. It doesn't take too long before the GPU has to do a huge amount of work to draw all of these rectangles. If the Graphics object is constantly changing then it should be cleared each frame. Or, if all you're doing is scaling it (like in my code above) then that's fine, just draw once on it and then scale it per frame instead. Link to comment Share on other sites More sharing options...
Ahmed Khalifa Posted August 23, 2018 Author Share Posted August 23, 2018 Thanks a lot, I didn't know about that stack part Link to comment Share on other sites More sharing options...
Tom Atom Posted August 24, 2018 Share Posted August 24, 2018 @Ahmed Khalifa Unfortunatelly, I also needed tint for BitmapText. Not beacuse I like it, but because sponsors still want to support old devices and for some of them, running in canvas is only solution. Finally, I wrote article on how to add this functionality to Phaser 3: http://sbcgames.io/phaser-3-adjust-bitmaptext-to-support-tint-in-canvas-rendering-mode/ It works for static BitmapText, but will not for DynamicBitmapText. Whole magic behind tint in Phaser 2 / PIXI is, that it creates small canvas for tinted sprite and renders tinted version into it. It rerenders it when sprite frame changes, etc. It than takes this prerendered canvas to display it on screen instead of frame from atlas. In Phaser 2 BitmapText is tinted character by character. In my solution whole tinted text is prerendered - this is reason, why it will not work with dynamic text. Link to comment Share on other sites More sharing options...
Ahmed Khalifa Posted August 24, 2018 Author Share Posted August 24, 2018 @Tom Atom Thanks so much, that is really great Link to comment Share on other sites More sharing options...
aylictal Posted February 24, 2019 Share Posted February 24, 2019 thank you for this post (i'm late as ever) but i ran into this issue with a strokeRect call and it for sure will happen the same way as a fillRect call where if you redraw without clearing it, it will tear your performance to shreds over time Link to comment Share on other sites More sharing options...
rich Posted March 5, 2019 Share Posted March 5, 2019 On 2/24/2019 at 2:27 AM, aylictal said: thank you for this post (i'm late as ever) but i ran into this issue with a strokeRect call and it for sure will happen the same way as a fillRect call where if you redraw without clearing it, it will tear your performance to shreds over time It really doesn't. Link to comment Share on other sites More sharing options...
aylictal Posted March 23, 2022 Share Posted March 23, 2022 Oh Sorry @Rich I never responded back but my comment was about a strokeRect call I did in my own code that I forgot to clear and the tab was consuming more and more memory over time as my game ran. This is what I meant. Link to comment Share on other sites More sharing options...
Recommended Posts