satoshinm / ThinkMap

A 3D web based mapviewer for Minecraft/Bukkit

Home Page:https://circleci.com/gh/satoshinm/ThinkMap

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Unusably slow WebGL interface rendering

satoshinm opened this issue · comments

Although it builds and runs, both ThinkMap 0.11.banana and CircleCI build 10 are unreasonably slow. 1.7.10 server browsing using Chrome 58.0.3029.110 and Safari TP 30. When trying to look around with the mouse, the camera moves only hesitantly.

I expected GWT would be slower than WebAssembly (compare to smoothness of https://github.com/satoshinm/NetCraft), but not this slow, maybe another issue.

screen shot 2017-05-28 at 4 40 41 pm

According to the Chrome profiler, most of the time is spent "scripting":

screen shot 2017-05-28 at 4 43 44 pm

Interacting with the debugger is unusably slow. But if I load about:blank then the captured profile can be interacted with, 71.1% time spent in _.Yb _.H anonymous() anonymous():

screen shot 2017-05-28 at 4 46 10 pm

Line 384 is:

function ie(a){return function(){var b;a:{var c=arguments,d;0!=pd&&(d=md(),2E3<d-rd&&(rd=d,qd=$wnd.setTimeout(od,10)));if(0==pd++){d=(sd(),td);var e,f;if(d.a){f=null;do e=d.a,d.a=null,f=vd(e,f);while(d.a);d.a=f}d=!0}else d=!1;try{b=a.apply(this,c);break a}finally{if(c=d)if(d=(sd(),td),d.b){f=null;do e=d.b,d.b=null,f=vd(e,f);while(d.b);d.b=f}--pd;c&&-1!=qd&&($wnd.clearTimeout(qd),qd=-1)}b=void 0}return b}}

Surprisingly large amount of time spent on GC (DOM GC: 674.7 ms, or 2.1%, minor GC: 25.7 ms 0.1%, major GC: 9.6 ms), wouldn't expect any garbage collection from the DOM? Then again this is JavaScript not asm.js/wasm. But would need to investigate further the slower tasks first. Line 369 takes up 76.6% (6843.8 ms):

_.Yb=function(a){a=li(a.a.t,this.g,this.i);var b;if(b=a){b=this.b;var c=this.e;b<a.a[c]||a.n?b=!1:(a.a[c]=b,b=!0)}if(b){b=this.a;var d;d=a.k[this.e];for(c=0;c<b.length;c++)d.b[c]=b[c];d=this.e;b=this.c;0==b.length?a.d[d]&&(b=a.d[d],a.f.e.o.o.deleteBuffer(b.a),b.a=null):(!a.d[d]&&(a.d[d]=new Fh(a.p,a.q)),c=a.f.e.o,d=a.d[d],!d.a&&(d.a=c.o.createBuffer()),d.b=~~(b.length/22),c.o.bindBuffer(34962,d.a),c.o.bufferData(34962,b,35044));b=this.e;var e=this.d,c=this.f;a.e[b]&&ui(a.e[b],null);a.e[b]&&0==e.b.length?

Creating, binding, deleting, and buffering data. There are a bunch of WebGL warnings:

RENDER WARNING: There is no texture bound to unit 1

up to 9, repeated until "WebGL: too many errors". WebGL texture binding problem?

Wherever the problem is, it is multiplied by loading many chunks. Changing this code in ./html/client/src/main/java/uk/co/thinkofdeath/thinkcraft/html/client/world/ClientWorld.java to load only one:

            Collections.sort(toLoad, new ChunkArraySorter(mapViewer.getCamera()));
            for (int[] pos : toLoad) {
                System.out.println("toLoad pos "+pos[0]+","+pos[1]);
                loadChunk(pos[0], pos[1]);
                break;
            }

interaction becomes usable, barely, though still slow (and bunch of WebGL warnings:

[.Offscreen-For-WebGL-0x7f94790e3c00]RENDER WARNING: there is no texture bound to the unit 1
(index):1 [.Offscreen-For-WebGL-0x7f94790e3c00]RENDER WARNING: there is no texture bound to the unit 2
(index):1 [.Offscreen-For-WebGL-0x7f94790e3c00]RENDER WARNING: there is no texture bound to the unit 3
(index):1 [.Offscreen-For-WebGL-0x7f94790e3c00]RENDER WARNING: there is no texture bound to the unit 4
(index):1 [.Offscreen-For-WebGL-0x7f94790e3c00]RENDER WARNING: there is no texture bound to the unit 5
(index):1 [.Offscreen-For-WebGL-0x7f94790e3c00]RENDER WARNING: there is no texture bound to the unit 6
(index):1 [.Offscreen-For-WebGL-0x7f94790e3c00]RENDER WARNING: there is no texture bound to the unit 7
(index):1 [.Offscreen-For-WebGL-0x7f94790e3c00]RENDER WARNING: there is no texture bound to the unit 8
(index):1 [.Offscreen-For-WebGL-0x7f94790e3c00]RENDER WARNING: there is no texture bound to the unit 9

chunk_fragment.glsl:

const int MAX_TEXTURES = 10;

...

    for (int i = 0; i < MAX_TEXTURES; i++) {
        if (tid == i) {
            colour = texture2D(textures[i], pos);
        }
    }