Closed Bug 1048196 Opened 10 years ago Closed 10 years ago

requestAnimationFrame does not work correctly anymore in Firefox 31

Categories

(Tech Evangelism Graveyard :: English US, defect)

defect
Not set
major

Tracking

(Not tracked)

RESOLVED WORKSFORME

People

(Reporter: GEverling.MBA2002, Unassigned)

References

()

Details

(Keywords: regression, reproducible, testcase)

User Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Firefox/31.0 (Beta/Release)
Build ID: 20140716183446

Steps to reproduce:

In Firefox 31, http://wsers.foxi.lu/Tutorial/WMOTUInvadersOO does not work anymore, although it works in Chrome and worked in previous Firefox versions up to at least version 29.


Actual results:

requestAnimationFrame calls the callback, but the images are not displayed. If I use setTimeOut instead of requestAnimationFrame, it works.


Expected results:

requestAnimationFrame calls the callback, and the images are displayed.
Severity: normal → critical
I can reproduce this on OS X. Still broken on Nightly. Not sure what's wrong, though, as the testcase is hardly a simple one - and in fact, the gameLoop bits are being hit fine, if you check in the debugger...
Severity: critical → major
Status: UNCONFIRMED → NEW
Component: Untriaged → General
Ever confirmed: true
OS: Windows 7 → All
Product: Firefox → Core
Hardware: x86_64 → All
I see the issue here in nightlies going back to November 2013 (so targeted at Firefox 28).  So presumably this was something that landed in nightlies back then but not in release until Firefox 31.

The one-day regression range on nightlies is http://hg.mozilla.org/mozilla-central/pushloghtml?fromchange=770de5942471&tochange=9ba3faa35c96

In that range, we have the checkin for bug 932322 which was in fact disabled in Firefox 28, 29, and 30 but shipped in Firefox 31.

The page has this bit at global scope:

  var requestAnimationFrame = function (win, t) {
      return win["webkitR" + t] || win["r" + t] || win["mozR" + t]
          || win["msR" + t] || function (fn) {
          setTimeout(fn, 1000 / 60)
      }
  }(window, "equestAnimationFrame");

Before bug 932322, this used to shadow the default requestAnimationFrame with undefined and therefore pick up the mozRequestAnimationFrame.  Now it picks up the default requestAnimationFrame.

In Chrome, it picks up webkitRequestAnimationFrame, since the code puts that before the standard version, unlike mozRequestAnimationFrame.

If I comment out this code so that the standard requestAnimationFrame is used in all browsers, the page stops working in Chrome as well.  If instead I change that code to put the moz-prefixed version next to the webkit-prefixed one, so it's picked up in preference to the standard one, then the page works in Firefox.

So the page is simply depending on NOT using the standard requestAnimationFrame.

And the reason for that is that the argument to the requestAnimationFrame callback is different for the standard version and the prefixed versions.  In the prefixed versions it's a value you can compare to "new Date" values.  In the standard version it's a value you can compare to performance.now() values.

In gameLoop, the script compares the argument (currTime) to this.lastAnimationTime and this.timeOfLastShot.  this.lastAnimationTime is set to this.timestamp(), which is defined as:

    // http://codeincomplete.com/posts/2013/12/4/javascript_game_foundations_the_game_loop
    timestamp: function () {
        return new Date().getTime(); /*window.performance && window.performance.now ?
            window.performance.now() :*/
    },

so the whole thing fails: it's comparing times with different zero bases and not getting the answers it expects.  If I change that timestamp() code to be the code at the link it's citing:

    timestamp: function() {
      return window.performance && window.performance.now ?
        window.performance.now() : new Date().getTime();
    },

then the game starts working with the standard requestAnimationFrame in all browsers.

All of which is to say this is a bug in the page: it screws up its usage of vendor-prefixed requestAnimationFrame, and screws it up differently for different prefixes, which is the only reason it ends up working in Chrome.  This page just needs to be fixed.
Assignee: nobody → english-us
Component: General → English US
Product: Core → Tech Evangelism
Version: 31 Branch → Trunk
Blocks: 932322
Sorry about that, I did not realize the transition to the standard requestAnimationFrame. My fault. Thanks for your help.
Status: NEW → RESOLVED
Closed: 10 years ago
Resolution: --- → WORKSFORME
Product: Tech Evangelism → Tech Evangelism Graveyard
You need to log in before you can comment on or make changes to this bug.