Possible sources of an asynchronous bug in a WebGLRenderingContext? - javascript

I have an animation loop running in which I'm getting an error that reads...
GL ERROR :GL_INVALID_OPERATION : glDrawElements: Source and destination textures of the draw are the same.
This error pops up after between 2 and 3 animation frame requests, depending on whether I've refreshed or hard refreshed the screen - and even then the timing of the error is not consistent. A hard refresh may occasionally delay the error from showing up until after 3 frame requests, but most of the time for both a refresh and hard refresh the error shows up after 2 frame requests. Based on those observations, the problem seems to be in an asynchronous component. I also have a simpler toy version of this loop running without any errors. I've been simplifying the buggy program more and more (it's now just displaying a non-moving cube) and still can't find the source of the problem.
The program is decently complex, so it's hard to determine what code to show here, so instead I'm hoping for an answer that may teach me a little about approaching a problem like this generally, so I can apply it whenever I hit similar situations: My question is, what are the top candidate areas in a program for a problem like this? Knowing that, I can focus my efforts.
I hope this makes sense - let me know if you need further clarification. Thanks!
Update:
This seems quite basic, but I will add that when I put no objects in the scene (cubes, axis helpers, etc.) and leave everything else the same, the error goes away.
Also, I'm wondering if this sort of error can occur because of a lost context? Like so.

You probably need to post your code but just guessing...
First off the error is exactly what it says it is. You have a texture attached to the current framebuffer. That same texture is also assigned to some texture unit.
Why that happens intermittently I can only guess. If you're loading textures from images or even from dataURLs they load async. Being in the cache or if you're testing locally they'll load quickly. So, my guess would be you're not correctly setting your texture units every frame (calling gl.activeTexture and gl.bindTexture for each texture unit used by your shaders). When your image is finally downloaded async you call gl.bindTexture to upload the texture. That ends up assigning a texture to whatever the current active texture unit is and messes up your setup.

Related

Wild time differences measured in Node.js program

I've noticed an odd behavior in a program I am working on. While it's probably my fault, I wanted to check if someone faced this before.
Both with console.time and performance-now my code has highly variable run time. I can't exactly paste it here because it's work related, but the workflow is:
start timer
load image via jimp
when image is loaded, scale image times 2
scan the image, transform pixels in zeroes and ones and put it into an array
log time
Some discrepancy is sure to be expected, but the results are so different I'm wondering what I did wrong. Average time is short, but the outliers are pretty... well, you can see on the image below.

JavaScript Canvas requestAnimationFrame freezing tab

I've been working on a 2D game in JavaScript using the canvas, and I found that requestAnimationFrame seems to make the game much smoother, which is great. However, the game has been freezing at random times ever since. The tab becomes stuck, and the game doesn't throw any errors, so I'm kind of at a loss. I have tried many things to manually debug it, such as constantly updating a LocalStorage variable, just displaying in the console, etc. Nothing is really giving me any results.
I can say that my experiments lead me to believe that there may be some strange asynchronous behavior associated with requestAnimationFrame; namely, I have noticed that if I change the size of something via socket.on, such as an array, and the game happens to be running a for-loop on that array, it sometimes crashes mid for-loop saying that the thing I'm referencing is undefined, even though I check for that right before the for-loop. Moreover, I noticed that when requestAnimationFrame calls code, such as my Game.update() function, sometimes the "this" object isn't properly referencing the object I'm in. ie., in Game.update(), this.draw_something() would throw an error. I have fixed those issues I believe, but I'm wondering if anyone has any insight into the overall nature of requestAnimationFrame.
The last thing I want to mention is that when the tab freezes, the memory begins to sky-rocket. It quickly goes from a few hundred MBs (from pre-loaded gfx, etc) to around 2 gigs, and continually increases.
I hope someone has some good feedback - and thanks in advance.

Chrome canvas becomes blank after waking up from standby mode

Our application downloads about 15meg of images and displays them in a html canvas. We are doing a bit of stress testing and have found that after we have about 10 tabs open if we put the computer in sleep mode, when it comes back the canvas is blank - it just shows plain white (this doesn't happen every time, but very frequently).
We hold the images in JavaScript Image objects, and I have inspected the memory in those and they still appear to be valid. I've tried to use the Chrome memory analysis by taking a snap shot before and after the error occurs, in some cases less memory is being used, in other cases more, so that didn't seem to tell me much.
I am curious if anyone has seen this before, and even if not, does anyone have pointers about debugging something similar. It would be perfectly sufficient if there was a way for us to determine if the error had occurred so we could trigger a reload of the images, but I'm afraid until I figure out what is causing it, I won't even know what to try and inspect.
#rtpg - the draw loop was continuing to run, but it would not display anything
For some reason the canvas would no longer update. I was unable to determine when the problem occurred but did figure out how to get the canvas to start displaying the images again. It was required that I resize the canvas (I change the width by one pixel) and then redraw (it's embarrassingly hackish). I current have it set to run every 30 seconds through setTimeout, but will probably change to window.onfocus once I can verify that gets called when coming out of sleep mode.
There are major canvas issues in Chrome 29.
You may want to check out and star this issue:
https://code.google.com/p/chromium/issues/detail?id=280153
(This stress test is failing too and may be related)

Removing a Raphael element causes it to crash sometimes?

I have a Raphael javascript program, where I have several (dozens, hundreds, whatever) circles written to the page, like so:
evo_sprite = paper.circle(evo.x, evo.y, this.evo_size);
Each circle has a limited amount of time I want it displayed, after which I want it destroyed so it doesn't slow stuff down.
When I do:
evo_sprite.hide();
I have no problems, but I know the sprite is still there, and thus still taking up memory.
So I tried:
evo_sprite.remove();
And got what APPEARED to be the same result (the circle is no longer displayed).
The only problem is that after some amount of time(seems random), my program freezes and I get the error message:
a1.paper is undefined
[Break On This Error] Raphael=(function(){var a=/[, ]+/,aO=/...eturn d;};an.el=ax[aY];return an;})();
Does this make sense to anybody? Am I calling remove incorrectly? How am I causing Raphael's code (on line 7 of the min file) to break just by calling remove on a circle?
It's difficult to know without seeing your code, but it looks like it is the Raphael canvas that isn't being found (I presume that's what a1.paper is).
Are you instantiating your Raphael canvas on document.onload (or $(document).ready with jQuery)? Make sure there aren't any closures in your code that make functions trying to operate outside the scope of a1.paper.
Then go right back to basics - try it with just a few circles to begin with, then 50, then 100. Then try it in different browsers and see whether it stops working in all of them. SVG is quite browser intensive, so creating thousands of circles might make some browsers break.

Force HTML5 canvas to redraw while doing heavy JavaScript processing?

This question is related to this older one, but I wanted to be sure I had the right answer before I started making major changes to my code.
I'm working on a very computation-intensive JavaScript program that needs to constantly update an image in an HTML5 canvas to draw an animation. As written now, the code draws all the frames of the animation in a tight loop without returning control to the browser, meaning that what's ultimately displayed is just the final frame. I'm pretty sure the only way to fix this is to split the animation code into smaller pieces that can be called reentrantly through a timeout event. Is this correct? Or is there a way to force the canvas to display its contents at a certain point even in the middle of a tight JavaScript loop?
I'm pretty sure the only way to fix this is to split the animation code into smaller pieces that can be called reentrantly through a timeout event. Is this correct?
This is correct.
Javascript is single threaded, so there's no way for anything else to happen while your logic is being executed. Your only choice is to "emulate" threading by splitting your logic up in to micro-chunks to be executed on timeouts.
You could use webworkers for this if they are available. Just calculate everything you need to do in the webworkers and post the result back when it's done. When you post the message back you can just refresh the image.
Calculations will be done in the background and your page only blocks while updating the image.

Categories

Resources