-
-
Notifications
You must be signed in to change notification settings - Fork 10.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Firefox's privacy.resistFingerprinting=true triggers assert in emscripten example #3644
Comments
Hello, Thanks for the report.
We need correct timing, it's used for dozens of things, double-click time, keyboard repeat rates, unlock delays after mouse wheeling, hovered idioms, drag to hold, garbage collection policies, any form of animation (fading in/out of dimming overlays). This is what the assert is guarding against. Running with series of dt==0.0f followed by large dt value is going to create hard to notice issues which might be even worst. If we have no way to bypass that, I think it should be something the backends support to automatically detect that situation on emscripten and turn the uneven time values into a smoothed set. Then it becomes the backend responsibility to handle it. If the code is obvious I don't mind adding that code in core imgui as an opt-in thing or an Emscripten-only thing, but someone has to write that code :)
Would you know how to enable those headers in the example Emscripten applications? |
Note that this code could technically be inserted between Basically it needs to:
Could you log the DeltaTime values you get from Firefox, from frame 0 and paste them here? That would help deciding on the right way to implement that smoothing algorithm, if we can't use the |
Thanks for having a look. I tried playing with the demo some more and you are right, there are funny issues: Doubleclick works, (positive) key repeat as well, but backspace tends to eat a couple characters in text inputs on a single press. Log of the first 61 framesDeltaTime: 0.016667 FrameCount: 0 DeltaTime: 0.000000 FrameCount: 1 DeltaTime: 0.000000 FrameCount: 2 DeltaTime: 0.100000 FrameCount: 3 X DeltaTime: 0.000000 FrameCount: 4 DeltaTime: 0.000000 FrameCount: 5 DeltaTime: 0.000000 FrameCount: 6 DeltaTime: 0.100000 FrameCount: 7 X DeltaTime: 0.000000 FrameCount: 8 DeltaTime: 0.000000 FrameCount: 9 DeltaTime: 0.100000 FrameCount: 10 X DeltaTime: 0.000000 FrameCount: 11 DeltaTime: 0.000000 FrameCount: 12 DeltaTime: 0.000000 FrameCount: 13 DeltaTime: 0.000000 FrameCount: 14 DeltaTime: 0.000000 FrameCount: 15 DeltaTime: 0.000000 FrameCount: 16 DeltaTime: 0.000000 FrameCount: 17 DeltaTime: 0.000000 FrameCount: 18 DeltaTime: 0.000000 FrameCount: 19 DeltaTime: 0.000000 FrameCount: 20 DeltaTime: 0.100000 FrameCount: 21 X DeltaTime: 0.000000 FrameCount: 22 DeltaTime: 0.000000 FrameCount: 23 DeltaTime: 0.000000 FrameCount: 24 DeltaTime: 0.000000 FrameCount: 25 DeltaTime: 0.000000 FrameCount: 26 DeltaTime: 0.100000 FrameCount: 27 X DeltaTime: 0.100000 FrameCount: 28 X DeltaTime: 0.000000 FrameCount: 29 DeltaTime: 0.000000 FrameCount: 30 DeltaTime: 0.000000 FrameCount: 31 DeltaTime: 0.000000 FrameCount: 32 DeltaTime: 0.000000 FrameCount: 33 DeltaTime: 0.000000 FrameCount: 34 DeltaTime: 0.100000 FrameCount: 35 X DeltaTime: 0.000000 FrameCount: 36 DeltaTime: 0.000000 FrameCount: 37 DeltaTime: 0.000000 FrameCount: 38 DeltaTime: 0.000000 FrameCount: 39 DeltaTime: 0.000000 FrameCount: 40 DeltaTime: 0.000000 FrameCount: 41 DeltaTime: 0.000000 FrameCount: 42 DeltaTime: 0.000000 FrameCount: 43 DeltaTime: 0.000000 FrameCount: 44 DeltaTime: 0.100000 FrameCount: 45 X DeltaTime: 0.000000 FrameCount: 46 DeltaTime: 0.100000 FrameCount: 47 X DeltaTime: 0.000000 FrameCount: 48 DeltaTime: 0.000000 FrameCount: 49 DeltaTime: 0.000000 FrameCount: 50 DeltaTime: 0.000000 FrameCount: 51 DeltaTime: 0.000000 FrameCount: 52 DeltaTime: 0.000000 FrameCount: 53 DeltaTime: 0.000000 FrameCount: 54 DeltaTime: 0.000000 FrameCount: 55 DeltaTime: 0.100000 FrameCount: 56 X DeltaTime: 0.000000 FrameCount: 57 DeltaTime: 0.100000 FrameCount: 58 X DeltaTime: 0.000000 FrameCount: 59 DeltaTime: 0.000000 FrameCount: 60 The value of frame 0 is stable across tests. Ignoring this the following 60 frames will be roughly 50 frames with 0.f delta and 10 with 0.1f. Roughly as the frame count between impacts is not predictable (by design), so it can be the next frame or (empirical) 11 more until the next impact. In other words from a DeltaTime view you are somewhere between 0.2f in the past/future. The emscripten example uses the SDL backend at the moment (I expect it to be similar with other backends), which calculates DeltaTime via if (io.DeltaTime == 0.f || io.DeltaTime == 0.1f)
io.DeltaTime = 1.f / 60.f; there I can workaround my problem for now until someone (= hopefully not me) feels bored enough to investigate a proper solution – I would presume keeping tabs on "accumulated diff time" vs. "real time" is more promising than trying the headers approach as headers tend to be hard to set in the wild. |
Sorry for late answer. Recently opened #6114 tried to tackles the same issue. (EDIT: not exactly, see post below) Some suggestions:
Starting from a helper, e.g. template<typename TYPE>
struct ImMovingAverage
{
// Internal Fields
ImVector<TYPE> Samples;
TYPE Accum;
int Idx;
int FillAmount;
// Functions
ImMovingAverage() { Accum = (TYPE)0; Idx = FillAmount = 0; }
void Init(int count) { Samples.resize(count); memset(Samples.Data, 0, (size_t)Samples.Size * sizeof(TYPE)); Accum = (TYPE)0; Idx = FillAmount = 0; }
void AddSample(TYPE v) { Accum += v - Samples[Idx]; Samples[Idx] = v; if (++Idx == Samples.Size) Idx = 0; if (FillAmount < Samples.Size) FillAmount++; }
TYPE GetAverage() const { return Accum / (TYPE)FillAmount; }
int GetSampleCount() const { return Samples.Size; }
bool IsFull() const { return FillAmount == Samples.Size; }
}; Applications feeds delta-time extrapolated from Arguably we could decide to move the responsibility of it to either the backend, either even dear imgui.. it's not hard to implement per-se, but the problem is that "enabling" the feature solely on |
My bad, I forgot that |
With 0749061 we made the core lib tolerate zero io.DeltaTime on Emscripten. |
It's not an Emscripten issue, it's a browser issue. Browser software is inherently untrusted. Some big brain security flaws rely on having an accurate, high-resolution timer. As such browsers don't provide one (at least not to the standard most desktop software is used to having.) The specification for high-resolution time specifically allows for reduced precision and accuracy. The only guarantee according to the spec is that you get is that the timer will be monotonic and have a resolution of at least 1 millisecond. For example, these days Firefox is only accurate to the millisecond, regardless of the (The documentation makes it sound like 100 ms is the default, but I believe that's no longer the case. The default for In general I think it's probably better to just accept browsers are janky and users fiddling with advanced config options makes them even more janky. We should just tolerate a delta time of 0 since really the only thing guaranteed by the spec is that it won't be negative. One thing that does still puzzle me though is that the Emscripten main loop is typically dispatched using (Emphasis on "typically" though, the spec makes no specific requirements. Even the basic MDN example for (Another possibility is that Emscripten might be scheduling the next dispatch at the start of the I'd have to dig into the Emscripten internals, but I wonder if it tries to "emulate" higher update rates when you request them. I know |
… a monotonically increasing value. (ocornut#6189, ocornut#6114, ocornut#3644)
Version/Branch of Dear ImGui:
Version: 1.80 WIP (17906)
Branch: master
Back-end/Renderer/Compiler/OS
Back-ends: emscripten_opengl3
Compiler: emcc 2.0.8 (using clang 11)
Operating System: Debian unstable
My Issue/Question:
Compiling the example application works just fine. It also runs just fine with Chromium (83.0.4103.116) and Firefox (83.0) in its default configuration, but if you are running Tor Browser or if you set
privacy.resistFingerprinting
in Firefox'sabout:config
totrue
the example will crash on a failed assert after the first frame (so you get a still image of correctly rendered frame 0).The assert in question is in imgui.cc:6917:
IM_ASSERT((g.IO.DeltaTime > 0.0f || g.FrameCount == 0) && "Need a positive DeltaTime!");
The reason is that
g.IO.DeltaTime
will be zero for most frames and only sometimes be 0.1f instead of reporting constantly a very precise timing of around 0.016f as the resolution for time is reduced (and jitter added). Some technical details can be found in the bugzilla entry and there also seems to be an option for sites requiring high precision (have not tried though).I am not quite sure what this assert is guarding against, but as 0.f is a sort-of positive value as well that could perhaps be changed to >=. Disabling this assert at least lets the demo run just fine: I presume some time-based animations and such will be a bit jittery (e.g. Widgets > Plot Widgets > Lines) if you are sensitive to it, but that seems acceptable compared to not being able to use an application at all in this configuration.
The text was updated successfully, but these errors were encountered: