diff --git a/dom/canvas/WebGL2ContextQueries.cpp b/dom/canvas/WebGL2ContextQueries.cpp index b3ffe264e6e6..1fec22d70e3d 100644 --- a/dom/canvas/WebGL2ContextQueries.cpp +++ b/dom/canvas/WebGL2ContextQueries.cpp @@ -6,6 +6,8 @@ #include "WebGL2Context.h" #include "GLContext.h" #include "WebGLQuery.h" +#include "gfxPrefs.h" +#include "nsThreadUtils.h" namespace mozilla { @@ -255,6 +257,7 @@ WebGL2Context::EndQuery(GLenum target) } UpdateBoundQuery(target, nullptr); + NS_DispatchToCurrentThread(new WebGLQuery::AvailableRunnable(activeQuery)); } already_AddRefed @@ -325,6 +328,11 @@ WebGL2Context::GetQueryParameter(JSContext*, WebGLQuery* query, GLenum pname, return; } + // We must wait for an event loop before the query can be available + if (!query->mCanBeAvailable && !gfxPrefs::WebGLImmediateQueries()) { + return; + } + MakeContextCurrent(); GLuint returned = 0; switch (pname) { diff --git a/dom/canvas/WebGLQuery.cpp b/dom/canvas/WebGLQuery.cpp index 016aa198d194..e557b8b4505c 100644 --- a/dom/canvas/WebGLQuery.cpp +++ b/dom/canvas/WebGLQuery.cpp @@ -20,6 +20,7 @@ WebGLQuery::WrapObject(JSContext* cx, JS::Handle givenProto) WebGLQuery::WebGLQuery(WebGLContext* webgl) : WebGLContextBoundObject(webgl) + , mCanBeAvailable(false) , mGLName(0) , mType(0) { diff --git a/dom/canvas/WebGLQuery.h b/dom/canvas/WebGLQuery.h index 5886a75ed8a5..7f02fb35d7e2 100644 --- a/dom/canvas/WebGLQuery.h +++ b/dom/canvas/WebGLQuery.h @@ -10,6 +10,7 @@ #include "nsWrapperCache.h" #include "WebGLObjectModel.h" +#include "nsThreadUtils.h" namespace mozilla { @@ -22,6 +23,19 @@ class WebGLQuery final public: explicit WebGLQuery(WebGLContext* webgl); + class AvailableRunnable final : public nsRunnable + { + public: + AvailableRunnable(WebGLQuery* query) : mQuery(query) { } + + NS_IMETHOD Run() override { + mQuery->mCanBeAvailable = true; + return NS_OK; + } + private: + const RefPtr mQuery; + }; + bool IsActive() const; bool HasEverBeenActive() const { @@ -42,6 +56,8 @@ public: NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLQuery) NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLQuery) + // Track whether the event loop has spun + bool mCanBeAvailable; private: ~WebGLQuery() { diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h index 7bb41fdc8eb9..bde9f242fae0 100644 --- a/gfx/thebes/gfxPrefs.h +++ b/gfx/thebes/gfxPrefs.h @@ -437,6 +437,7 @@ private: DECL_GFX_PREF(Live, "webgl.msaa-force", WebGLForceMSAA, bool, false); DECL_GFX_PREF(Live, "webgl.prefer-16bpp", WebGLPrefer16bpp, bool, false); DECL_GFX_PREF(Live, "webgl.restore-context-when-visible", WebGLRestoreWhenVisible, bool, true); + DECL_GFX_PREF(Live, "webgl.allow-immediate-queries", WebGLImmediateQueries, bool, false); DECL_GFX_PREF(Live, "webgl.webgl2-compat-mode", WebGL2CompatMode, bool, false);