Jump to content

Why is webgl so slow in firefox?


jloa
 Share

Recommended Posts

First of all here are the specs of my pc:
- MS Windows 7 64-bit SP1
- Intel® Core i5-4570 CPU @ 3.20GHz 4-core
- 16 gb ddr3 ram @ 2300 mhz
- NVIDIA GeForce GTX 660, 2 gb dd5 ram (driver version: 9.18.13.3221)
- Firefox 31, latest (Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Firefox/31.0)
 
Here are the graphics settings in firefox (gpu acc enabled, webgl enabled, direct2D enabled etc...)

{  "application": {    "name": "Firefox",    "version": "31.0",    "userAgent": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Firefox/31.0",    "supportURL": "https://support.mozilla.org/1/firefox/31.0/WINNT/en-US/"  }  "modifiedPreferences": {    "dom.ipc.plugins.enabled.npietab2.dll": true,    "dom.mozApps.used": true,    "gfx.direct3d.last_used_feature_level_idx": 0,  },  "graphics": {    "numTotalWindows": 2,    "numAcceleratedWindows": 2,    "windowLayerManagerType": "Direct3D 10",    "windowLayerManagerRemote": false,    "adapterDescription": "NVIDIA GeForce GTX 660 ",    "adapterVendorID": "0x10de",    "adapterDeviceID": "0x11c0",    "adapterRAM": "2048",    "adapterDrivers": "nvd3dumx,nvwgf2umx,nvwgf2umx nvd3dum,nvwgf2um,nvwgf2um",    "driverVersion": "9.18.13.3221",    "driverDate": "12-19-2013",    "adapterDescription2": "",    "adapterVendorID2": "",    "adapterDeviceID2": "",    "adapterRAM2": "",    "adapterDrivers2": "",    "driverVersion2": "",    "driverDate2": "",    "isGPU2Active": false,    "direct2DEnabled": true,    "directWriteEnabled": true,    "directWriteVersion": "6.2.9200.16492",    "webglRenderer": "Google Inc. -- ANGLE (NVIDIA GeForce GTX 660  Direct3D9Ex vs_3_0 ps_3_0)",    "info": {      "AzureCanvasBackend": "direct2d",      "AzureSkiaAccelerated": 0,      "AzureFallbackCanvasBackend": "cairo",      "AzureContentBackend": "direct2d"    }  }}

But still, firefox lags like hell when using Phaser.WEBGL mode when using simple text/lines. Also from time to time fps just drop like 5-7 fps and then goes back even on a white blank project.

 

Test it yourself:

1. Open official example in firefox http://examples.phaser.io/_site/view_full.html?d=games&f=tanks.js&t=tanks

2. Open the browser console (press ctrl + shift + j or go to Developer >> browser console)

3. Inject this code in the console

// for fps measuringgame.time.advancedTiming = true;// override the original render() method game.state.onRenderCallback = function(){  game.debug.text('fps: '+game.time.fps, 32, 20);}

4. Check the fps (in my case drops to 54-56)

5. Inject this code in the console

// override the original render() method game.state.onRenderCallback = function(){  // welcome to the Laggy-Land :-)  game.debug.text('fps: '+game.time.fps, 32, 20);  game.debug.text('Enemies: ' + enemiesAlive + ' / ' + enemiesTotal, 32, 40);  game.debug.text('Enemies: ' + enemiesAlive + ' / ' + enemiesTotal, 32, 60);  game.debug.text('Enemies: ' + enemiesAlive + ' / ' + enemiesTotal, 32, 80);  game.debug.text('Enemies: ' + enemiesAlive + ' / ' + enemiesTotal, 32, 100);  game.debug.text('Enemies: ' + enemiesAlive + ' / ' + enemiesTotal, 32, 120);  game.debug.text('Enemies: ' + enemiesAlive + ' / ' + enemiesTotal, 32, 140);  game.debug.text('Enemies: ' + enemiesAlive + ' / ' + enemiesTotal, 32, 160)}

6. Check the fps (in my case it drops to 24-26)

 

The webGL renderer not able to render 8 texts? How? Why?!

I've test three.js demos - all work perfectly on this hw setup in firefox. Also tested pixie demos - same, works perfectly 60/60 fps.

 

Here a screenshot

post-9831-0-32416700-1407323839_thumb.pn

 

 

PS: also i've noticed that in IE and Firefox on either canvas or webgl mode sprites twitch from time to time, happens totally random - the sprite moves smooth, fps is 60 and then it just starts twitching while moving without fps drops. Chrome works perfectly of either modes, no glitches, no twitching - perfecto.

Link to comment
Share on other sites

I'm not a Phaser expert (never used it). But from what I see each time you call game.debug.text it write text into a canvas and upload the canvas to GPU.

 

So, in your script, you upload 8 textures per frame to GPU. Don't expect it to be fast.

Link to comment
Share on other sites

@HappyEnd is right,

 

Look for the doc for game.debug -> https://github.com/photonstorm/phaser/blob/8421cfc4004d90db1a3d49eb29ec4a186d05c4e0/src/utils/Debug.js

 

It explains how the debug rendering works, and indeed what you did is forcing to push a window sized texture 9 times to the GPU at each game cycle.

 

Chrome may be faster for doing this operation, but it's not just about displaying a text, and therefore not as cheap as you imagine

Link to comment
Share on other sites

And why does it use 8 canvas instances rather than render the whole scene on 1? O_o

From my expirience it should not matter how many layers/objects/tilemaps/sprites etc (display objects) you have. The engine should combine then according to the z-index like a sadwitch and render a single birmapdata (all objects combined) on 1 canvas/texture. No matter what the case is. Doesn't it work that way in phaser?

You grab all your objects which are bitmapdatas with a corresponding transform matrix (x/y/rotation/scale etc) and just paint them on a single canvas (texture).

 

I think that's the reason why my project super lags when i use 10-layer tilemap with a lockon camera, if phaser really dupes canvas/textures.

Then it's time to rewrite the renderer in that case.

 

Some meta-code how the rendering should be done

// canvas/texture// cleargfx.clear();// start renderinggfx.begin();...// render each childfor each displayOjbect{gfx.draw(child);}...// only then output a single canvas/texturegfx.end();
Link to comment
Share on other sites

Ok, i've decided to make a blank project to test the lags.

Just a simple box 20x20 pixels flying around. So, when i fly around it still lags. Drops fps to 54-56 on a blank project.

What am i doing wrong? Btw switching to canvas doesn't help. Same drops to 54-56 fps.

var ns = ns || {};var box;(function(ns){	var cursors;	var worldInfo = {		'w': 1000,		'h': 800,	};	var preload = function()	{		game.load.image('box', 'assets/i/box.png');	};	var create = function()	{		game.time.advancedTiming = true;		game.world.setBounds(0, 0, worldInfo.w, worldInfo.h);				// stage		game.stage.disableVisibilityChange = true;		game.stage.backgroundColor = '#ffffff';				// physics		game.physics.startSystem(Phaser.Physics.P2JS);		game.physics.p2.setBounds(0, 0, worldInfo.w, worldInfo.h, true, true, true, true, false);		game.physics.p2.useElapsedTime = true;		game.physics.p2.applyDamping = true;		game.physics.p2.setWorldMaterial(game.physics.p2.createMaterial('worldMaterial'), true, true, true, true);		box = game.add.sprite(200, 200, 'box', 0);		game.physics.p2.enable(box);		box.body.damphing		box.body.mass = 1;		box.body.damping = .1;		box.body.angularDamping = .1;					// camera		game.camera.follow(box, Phaser.Camera.FOLLOW_LOCKON);		// cursors		cursors = game.input.keyboard.createCursorKeys();	};		var update = function()	{		var force = 10;		if(cursors.left.isDown)		{			box.body.applyForce([force, 0], box.x, box.y);		}		else if(cursors.right.isDown)		{			box.body.applyForce([-force, 0], box.x, box.y);		}				if(cursors.up.isDown)		{			box.body.applyForce([0, force], box.x, box.y);		}		else if(cursors.down.isDown)		{					box.body.applyForce([0, -force], box.x, box.y);		}	};	var render = function()	{			};	game = new Phaser.Game(		1000,		800,		Phaser.WEBGL,		'game',		{ preload: preload, create: create, update: update, render: render }	);})(ns);
Link to comment
Share on other sites

Ok, so can someone of you guys that know the architecture of phaser exaplain me the workflow of the lib so that i save my tike reading all the source code?

 

So far i thought the workflow was similar to this:

 

- preload assets, create cache, for bitmaps create images and cache them

- create and setup all managers (stage, states, physics etc)

- create the renderer (a single canvas or single texture)

- ready for ticks

 

every tick:

- clear the canvas/texture

- call preUpdate() all stuff (cache, states, stage etc this includes physics, display objects)

- call user defined update() stuff

- call update on all managers (physics, display objects etc)

- call postUpdate() on all managers (physics, display objects etc)

- call render() on all display objects (let them modify their own bitmapdatas with filters/blend modes, transform matrixes etc)

- call renderer.render() - cycle through all display objects, grab their final bitmapdata and draw all those bitmapdatas it on 1 single canvas/texture according to z-index)

- call user defined render()

 

No need to create more than 1 canvas or texture. As a result - performance depends only on code optimization and loop-length, not on rendering.

Does phaser work so?

 

I hope Richard sees this and writes back :/

Edited by jloa
Link to comment
Share on other sites

  • 1 year later...

Hmm yes it is debug causing the problem.
 
I removed the following line in my project and it works smoothly.
 

this.game.debug.body(this.player);

 
Also, changing rendering to canvas made the movement smooth again. I'm surprised with Phaser.AUTO that it's don't switch.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...