Bug 1390386 - Add GLContext::mImplicitMakeCurrent. - r=jrmuizel
☠☠ backed out by fdbcfc9b7987 ☠ ☠
authorJeff Gilbert <jgilbert@mozilla.com>
Thu, 10 Aug 2017 18:01:04 -0700
changeset 427549 9d16670edeb5a831913ae92469c5754a768b9b07
parent 427548 d1286d0d2c792751472c807f75996c9fc34220d1
child 427550 1314405cf812ecb8757a1e0d9ce632d042c3916d
push id1567
push userjlorenzo@mozilla.com
push dateThu, 02 Nov 2017 12:36:05 +0000
treeherdermozilla-release@e512c14a0406 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1390386
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1390386 - Add GLContext::mImplicitMakeCurrent. - r=jrmuizel MozReview-Commit-ID: 5iyGHNzoCpd
dom/canvas/WebGLContext.cpp
dom/canvas/WebGLContext.h
gfx/gl/GLContext.cpp
gfx/gl/GLContext.h
--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -1080,17 +1080,17 @@ WebGLContext::SetDimensions(int32_t sign
     if (!gl->Caps().stencil)
         mOptions.stencil = false;
 
     mOptions.antialias = gl->Caps().antialias;
 
     //////
     // Initial setup.
 
-    MakeContextCurrent();
+    gl->mImplicitMakeCurrent = true;
 
     gl->fViewport(0, 0, mWidth, mHeight);
     mViewportX = mViewportY = 0;
     mViewportWidth = mWidth;
     mViewportHeight = mHeight;
 
     gl->fScissor(0, 0, mWidth, mHeight);
     gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
@@ -1926,22 +1926,16 @@ WebGLContext::ForceRestoreContext()
     printf_stderr("WebGL(%p)::ForceRestoreContext\n", this);
     mContextStatus = ContextLostAwaitingRestore;
     mAllowContextRestore = true; // Hey, you did say 'force'.
 
     // Queue up a task, since we know the status changed.
     EnqueueUpdateContextLossStatus();
 }
 
-void
-WebGLContext::MakeContextCurrent() const
-{
-    gl->MakeCurrent();
-}
-
 already_AddRefed<mozilla::gfx::SourceSurface>
 WebGLContext::GetSurfaceSnapshot(gfxAlphaType* const out_alphaType)
 {
     if (!gl)
         return nullptr;
 
     const auto surfFormat = mOptions.alpha ? SurfaceFormat::B8G8R8A8
                                            : SurfaceFormat::B8G8R8X8;
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -1710,17 +1710,17 @@ public:
                                  uint8_t** const out_bytes, size_t* const out_byteLen);
 
 protected:
     ////
 
     void Invalidate();
     void DestroyResourcesAndContext();
 
-    void MakeContextCurrent() const;
+    void MakeContextCurrent() const { } // MakeCurrent is implicit now.
 
     // helpers
 
     bool ConvertImage(size_t width, size_t height, size_t srcStride,
                       size_t dstStride, const uint8_t* src, uint8_t* dst,
                       WebGLTexelFormat srcFormat, bool srcPremultiplied,
                       WebGLTexelFormat dstFormat, bool dstPremultiplied,
                       size_t dstTexelSize);
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -262,17 +262,18 @@ ChooseDebugFlags(CreateContextFlags crea
     }
 #endif
 
     return debugFlags;
 }
 
 GLContext::GLContext(CreateContextFlags flags, const SurfaceCaps& caps,
                      GLContext* sharedContext, bool isOffscreen, bool useTLSIsCurrent)
-  : mIsOffscreen(isOffscreen),
+  : mImplicitMakeCurrent(false),
+    mIsOffscreen(isOffscreen),
     mContextLost(false),
     mUseTLSIsCurrent(ShouldUseTLSIsCurrent(useTLSIsCurrent)),
     mVersion(0),
     mProfile(ContextProfile::Unknown),
     mShadingLanguageVersion(0),
     mVendor(GLVendor::Other),
     mRenderer(GLRenderer::Other),
     mTopError(LOCAL_GL_NO_ERROR),
@@ -3070,10 +3071,69 @@ GLContext::ResetSyncCallCount(const char
     if (ShouldSpew()) {
         printf_stderr("On %s, mSyncGLCallCount = %" PRIu64 "\n",
                        resetReason, mSyncGLCallCount);
     }
 
     mSyncGLCallCount = 0;
 }
 
+// --
+
+void
+GLContext::BeforeGLCall_Debug(const char* const funcName) const
+{
+    MOZ_ASSERT(mDebugFlags);
+
+    FlushErrors();
+
+    if (mDebugFlags & DebugFlagTrace) {
+        printf_stderr("[gl:%p] > %s\n", this, funcName);
+    }
+
+    GLContext* tlsContext = (GLContext*)PR_GetThreadPrivate(sCurrentGLContextTLS);
+    if (this != tlsContext) {
+        printf_stderr("Fatal: %s called on non-current context %p. The"
+                      " current context for this thread is %p.\n",
+                      funcName, this, tlsContext);
+        MOZ_CRASH("GFX: GLContext is not current.");
+    }
+}
+
+void
+GLContext::AfterGLCall_Debug(const char* const funcName) const
+{
+    MOZ_ASSERT(mDebugFlags);
+
+    // calling fFinish() immediately after every GL call makes sure that if this GL command crashes,
+    // the stack trace will actually point to it. Otherwise, OpenGL being an asynchronous API, stack traces
+    // tend to be meaningless
+    mSymbols.fFinish();
+    GLenum err = FlushErrors();
+
+    if (mDebugFlags & DebugFlagTrace) {
+        printf_stderr("[gl:%p] < %s [%s (0x%04x)]\n", this, funcName,
+                      GLErrorToString(err), err);
+    }
+
+    if (err != LOCAL_GL_NO_ERROR &&
+        !mLocalErrorScopeStack.size())
+    {
+        printf_stderr("[gl:%p] %s: Generated unexpected %s error."
+                      " (0x%04x)\n", this, funcName,
+                      GLErrorToString(err), err);
+
+        if (mDebugFlags & DebugFlagAbortOnError) {
+            MOZ_CRASH("Unexpected error with MOZ_GL_DEBUG_ABORT_ON_ERROR. (Run"
+                      " with MOZ_GL_DEBUG_ABORT_ON_ERROR=0 to disable)");
+        }
+    }
+}
+
+/*static*/ void
+GLContext::OnImplicitMakeCurrentFailure(const char* const funcName)
+{
+    gfxCriticalError() << "Ignoring call to " << funcName << " with failed"
+                       << " mImplicitMakeCurrent.";
+}
+
 } /* namespace gl */
 } /* namespace mozilla */
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -194,16 +194,18 @@ class GLContext
     : public GLLibraryLoader
     , public GenericAtomicRefCounted
     , public SupportsWeakPtr<GLContext>
 {
 public:
     MOZ_DECLARE_WEAKREFERENCE_TYPENAME(GLContext)
     static MOZ_THREAD_LOCAL(const GLContext*) sCurrentContext;
 
+    bool mImplicitMakeCurrent;
+
 // -----------------------------------------------------------------------------
 // basic getters
 public:
 
     /**
      * Returns true if the context is using ANGLE. This should only be overridden
      * for an ANGLE implementation.
      */
@@ -648,136 +650,105 @@ private:
                        GLsizei length,
                        const GLchar* message);
 
 
 // -----------------------------------------------------------------------------
 // MOZ_GL_DEBUG implementation
 private:
 
-#undef BEFORE_GL_CALL
-#undef AFTER_GL_CALL
-
-#ifdef MOZ_GL_DEBUG
-
 #ifndef MOZ_FUNCTION_NAME
 # ifdef __GNUC__
 #  define MOZ_FUNCTION_NAME __PRETTY_FUNCTION__
 # elif defined(_MSC_VER)
 #  define MOZ_FUNCTION_NAME __FUNCTION__
 # else
 #  define MOZ_FUNCTION_NAME __func__  // defined in C99, supported in various C++ compilers. Just raw function name.
 # endif
 #endif
 
-    void BeforeGLCall(const char* funcName) {
+#ifdef MOZ_WIDGET_ANDROID
+// Record the name of the GL call for better hang stacks on Android.
+#define ANDROID_ONLY_PROFILER_LABEL AUTO_PROFILER_LABEL(__func__, GRAPHICS);
+#else
+#define ANDROID_ONLY_PROFILER_LABEL
+#endif
+
+#define BEFORE_GL_CALL \
+        ANDROID_ONLY_PROFILER_LABEL \
+        if (BeforeGLCall(MOZ_FUNCTION_NAME)) { \
+            do { } while (0)
+
+#define AFTER_GL_CALL \
+            AfterGLCall(MOZ_FUNCTION_NAME); \
+        } \
+        do { } while (0)
+
+    void BeforeGLCall_Debug(const char* funcName) const;
+    void AfterGLCall_Debug(const char* funcName) const;
+    static void OnImplicitMakeCurrentFailure(const char* funcName);
+
+    bool BeforeGLCall(const char* const funcName) const {
+        if (mImplicitMakeCurrent) {
+            if (MOZ_UNLIKELY( !MakeCurrent() )) {
+                OnImplicitMakeCurrentFailure(funcName);
+                return false;
+            }
+        }
         MOZ_ASSERT(IsCurrent());
 
         if (mDebugFlags) {
-            FlushErrors();
-
-            if (mDebugFlags & DebugFlagTrace) {
-                printf_stderr("[gl:%p] > %s\n", this, funcName);
-            }
-
-            GLContext* tlsContext = (GLContext*)PR_GetThreadPrivate(sCurrentGLContextTLS);
-            if (this != tlsContext) {
-                printf_stderr("Fatal: %s called on non-current context %p. The"
-                              " current context for this thread is %p.\n",
-                              funcName, this, tlsContext);
-                MOZ_CRASH("GFX: GLContext is not current.");
-            }
+            BeforeGLCall_Debug(funcName);
         }
-    }
-
-    void AfterGLCall(const char* funcName) {
+        return true;
+    }
+
+    void AfterGLCall(const char* const funcName) const {
         if (mDebugFlags) {
-            // calling fFinish() immediately after every GL call makes sure that if this GL command crashes,
-            // the stack trace will actually point to it. Otherwise, OpenGL being an asynchronous API, stack traces
-            // tend to be meaningless
-            mSymbols.fFinish();
-            GLenum err = FlushErrors();
-
-            if (mDebugFlags & DebugFlagTrace) {
-                printf_stderr("[gl:%p] < %s [%s (0x%04x)]\n", this, funcName,
-                              GLErrorToString(err), err);
-            }
-
-            if (err != LOCAL_GL_NO_ERROR &&
-                !mLocalErrorScopeStack.size())
-            {
-                printf_stderr("[gl:%p] %s: Generated unexpected %s error."
-                              " (0x%04x)\n", this, funcName,
-                              GLErrorToString(err), err);
-
-                if (mDebugFlags & DebugFlagAbortOnError) {
-                    MOZ_CRASH("Unexpected error with MOZ_GL_DEBUG_ABORT_ON_ERROR. (Run"
-                              " with MOZ_GL_DEBUG_ABORT_ON_ERROR=0 to disable)");
-                }
-            }
+            AfterGLCall_Debug(funcName);
         }
     }
 
     GLContext* TrackingContext()
     {
         GLContext* tip = this;
         while (tip->mSharedContext)
             tip = tip->mSharedContext;
         return tip;
     }
 
     static void AssertNotPassingStackBufferToTheGL(const void* ptr);
 
-#ifdef MOZ_WIDGET_ANDROID
-// Record the name of the GL call for better hang stacks on Android.
-#define BEFORE_GL_CALL                              \
-            AUTO_PROFILER_LABEL(__func__, GRAPHICS);\
-            BeforeGLCall(MOZ_FUNCTION_NAME)
-#else
-#define BEFORE_GL_CALL                              \
-            do {                                    \
-                BeforeGLCall(MOZ_FUNCTION_NAME);    \
-            } while (0)
-#endif
-
-#define AFTER_GL_CALL                               \
-            do {                                    \
-                AfterGLCall(MOZ_FUNCTION_NAME);     \
-            } while (0)
+#ifdef MOZ_GL_DEBUG
 
 #define TRACKING_CONTEXT(a)                         \
             do {                                    \
                 TrackingContext()->a;               \
             } while (0)
 
 #define ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(ptr) AssertNotPassingStackBufferToTheGL(ptr)
 
-#else // ifdef MOZ_GL_DEBUG
-
-#ifdef MOZ_WIDGET_ANDROID
-// Record the name of the GL call for better hang stacks on Android.
-#define BEFORE_GL_CALL AUTO_PROFILER_LABEL(__func__, GRAPHICS)
-#else
-#define BEFORE_GL_CALL do { } while (0)
-#endif
-#define AFTER_GL_CALL do { } while (0)
-#define TRACKING_CONTEXT(a) do {} while (0)
-#define ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(ptr) do {} while (0)
-
-#endif // ifdef MOZ_GL_DEBUG
-
 #define ASSERT_SYMBOL_PRESENT(func) \
             do {\
                 MOZ_ASSERT(strstr(MOZ_FUNCTION_NAME, #func) != nullptr, "Mismatched symbol check.");\
                 if (MOZ_UNLIKELY(!mSymbols.func)) {\
                     printf_stderr("RUNTIME ASSERT: Uninitialized GL function: %s\n", #func);\
                     MOZ_CRASH("GFX: Uninitialized GL function");\
                 }\
             } while (0)
 
+#else // ifdef MOZ_GL_DEBUG
+
+#define TRACKING_CONTEXT(a) do {} while (0)
+#define ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(ptr) do {} while (0)
+#define ASSERT_SYMBOL_PRESENT(func) do {} while (0)
+
+#endif // ifdef MOZ_GL_DEBUG
+
+
     // Do whatever setup is necessary to draw to our offscreen FBO, if it's
     // bound.
     void BeforeGLDrawCall() { }
 
     // Do whatever tear-down is necessary after drawing to our offscreen FBO,
     // if it's bound.
     void AfterGLDrawCall();
 
@@ -1178,18 +1149,19 @@ public:
     void fGetAttachedShaders(GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders) {
         BEFORE_GL_CALL;
         mSymbols.fGetAttachedShaders(program, maxCount, count, shaders);
         OnSyncCall();
         AFTER_GL_CALL;
     }
 
     GLint fGetAttribLocation(GLuint program, const GLchar* name) {
-        BEFORE_GL_CALL;
-        GLint retval = mSymbols.fGetAttribLocation(program, name);
+        GLint retval = 0;
+        BEFORE_GL_CALL;
+        retval = mSymbols.fGetAttribLocation(program, name);
         OnSyncCall();
         AFTER_GL_CALL;
         return retval;
     }
 
 private:
     void raw_fGetIntegerv(GLenum pname, GLint* params) {
         BEFORE_GL_CALL;
@@ -1231,19 +1203,20 @@ public:
     void fGetBufferParameteriv(GLenum target, GLenum pname, GLint* params) {
         BEFORE_GL_CALL;
         mSymbols.fGetBufferParameteriv(target, pname, params);
         OnSyncCall();
         AFTER_GL_CALL;
     }
 
     GLuint fGetDebugMessageLog(GLuint count, GLsizei bufsize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog) {
+        GLuint ret = 0;
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetDebugMessageLog);
-        GLuint ret = mSymbols.fGetDebugMessageLog(count, bufsize, sources, types, ids, severities, lengths, messageLog);
+        ret = mSymbols.fGetDebugMessageLog(count, bufsize, sources, types, ids, severities, lengths, messageLog);
         OnSyncCall();
         AFTER_GL_CALL;
         return ret;
     }
 
     void fGetPointerv(GLenum pname, GLvoid** params) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetPointerv);
@@ -1302,18 +1275,19 @@ public:
 
     void fTexParameterf(GLenum target, GLenum pname, GLfloat param) {
         BEFORE_GL_CALL;
         mSymbols.fTexParameterf(target, pname, param);
         AFTER_GL_CALL;
     }
 
     const GLubyte* fGetString(GLenum name) {
-        BEFORE_GL_CALL;
-        const GLubyte* result = mSymbols.fGetString(name);
+        const GLubyte* result = nullptr;
+        BEFORE_GL_CALL;
+        result = mSymbols.fGetString(name);
         OnSyncCall();
         AFTER_GL_CALL;
         return result;
     }
 
     void fGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* img) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetTexImage);
@@ -1363,18 +1337,19 @@ public:
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetUniformuiv);
         mSymbols.fGetUniformuiv(program, location, params);
         OnSyncCall();
         AFTER_GL_CALL;
     }
 
     GLint fGetUniformLocation (GLint programObj, const GLchar* name) {
-        BEFORE_GL_CALL;
-        GLint retval = mSymbols.fGetUniformLocation(programObj, name);
+        GLint retval = 0;
+        BEFORE_GL_CALL;
+        retval = mSymbols.fGetUniformLocation(programObj, name);
         OnSyncCall();
         AFTER_GL_CALL;
         return retval;
     }
 
     void fGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* retval) {
         BEFORE_GL_CALL;
         mSymbols.fGetVertexAttribfv(index, pname, retval);
@@ -1398,47 +1373,52 @@ public:
 
     void fHint(GLenum target, GLenum mode) {
         BEFORE_GL_CALL;
         mSymbols.fHint(target, mode);
         AFTER_GL_CALL;
     }
 
     realGLboolean fIsBuffer(GLuint buffer) {
-        BEFORE_GL_CALL;
-        realGLboolean retval = mSymbols.fIsBuffer(buffer);
+        realGLboolean retval = false;
+        BEFORE_GL_CALL;
+        retval = mSymbols.fIsBuffer(buffer);
         OnSyncCall();
         AFTER_GL_CALL;
         return retval;
     }
 
     realGLboolean fIsEnabled(GLenum capability) {
-        BEFORE_GL_CALL;
-        realGLboolean retval = mSymbols.fIsEnabled(capability);
+        realGLboolean retval = false;
+        BEFORE_GL_CALL;
+        retval = mSymbols.fIsEnabled(capability);
         AFTER_GL_CALL;
         return retval;
     }
 
     realGLboolean fIsProgram(GLuint program) {
-        BEFORE_GL_CALL;
-        realGLboolean retval = mSymbols.fIsProgram(program);
+        realGLboolean retval = false;
+        BEFORE_GL_CALL;
+        retval = mSymbols.fIsProgram(program);
         AFTER_GL_CALL;
         return retval;
     }
 
     realGLboolean fIsShader(GLuint shader) {
-        BEFORE_GL_CALL;
-        realGLboolean retval = mSymbols.fIsShader(shader);
+        realGLboolean retval = false;
+        BEFORE_GL_CALL;
+        retval = mSymbols.fIsShader(shader);
         AFTER_GL_CALL;
         return retval;
     }
 
     realGLboolean fIsTexture(GLuint texture) {
-        BEFORE_GL_CALL;
-        realGLboolean retval = mSymbols.fIsTexture(texture);
+        realGLboolean retval = false;
+        BEFORE_GL_CALL;
+        retval = mSymbols.fIsTexture(texture);
         AFTER_GL_CALL;
         return retval;
     }
 
     void fLineWidth(GLfloat width) {
         BEFORE_GL_CALL;
         mSymbols.fLineWidth(width);
         AFTER_GL_CALL;
@@ -1868,16 +1848,33 @@ public:
     }
 
     void fVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) {
         BEFORE_GL_CALL;
         mSymbols.fVertexPointer(size, type, stride, pointer);
         AFTER_GL_CALL;
     }
 
+    void fViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
+        if (mViewportRect[0] == x &&
+            mViewportRect[1] == y &&
+            mViewportRect[2] == width &&
+            mViewportRect[3] == height)
+        {
+            return;
+        }
+        mViewportRect[0] = x;
+        mViewportRect[1] = y;
+        mViewportRect[2] = width;
+        mViewportRect[3] = height;
+        BEFORE_GL_CALL;
+        mSymbols.fViewport(x, y, width, height);
+        AFTER_GL_CALL;
+    }
+
     void fCompileShader(GLuint shader) {
         BEFORE_GL_CALL;
         mSymbols.fCompileShader(shader);
         AFTER_GL_CALL;
     }
 
 private:
 
@@ -1958,18 +1955,19 @@ private:
 public:
     void fBindRenderbuffer(GLenum target, GLuint renderbuffer) {
         BEFORE_GL_CALL;
         mSymbols.fBindRenderbuffer(target, renderbuffer);
         AFTER_GL_CALL;
     }
 
     GLenum fCheckFramebufferStatus(GLenum target) {
-        BEFORE_GL_CALL;
-        GLenum retval = mSymbols.fCheckFramebufferStatus(target);
+        GLenum retval = 0;
+        BEFORE_GL_CALL;
+        retval = mSymbols.fCheckFramebufferStatus(target);
         OnSyncCall();
         AFTER_GL_CALL;
         return retval;
     }
 
     void fFramebufferRenderbuffer(GLenum target, GLenum attachmentPoint, GLenum renderbufferTarget, GLuint renderbuffer) {
         BEFORE_GL_CALL;
         mSymbols.fFramebufferRenderbuffer(target, attachmentPoint, renderbufferTarget, renderbuffer);
@@ -2002,27 +2000,29 @@ public:
     void fGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* value) {
         BEFORE_GL_CALL;
         mSymbols.fGetRenderbufferParameteriv(target, pname, value);
         OnSyncCall();
         AFTER_GL_CALL;
     }
 
     realGLboolean fIsFramebuffer (GLuint framebuffer) {
-        BEFORE_GL_CALL;
-        realGLboolean retval = mSymbols.fIsFramebuffer(framebuffer);
+        realGLboolean retval = false;
+        BEFORE_GL_CALL;
+        retval = mSymbols.fIsFramebuffer(framebuffer);
         OnSyncCall();
         AFTER_GL_CALL;
         return retval;
     }
 
 public:
     realGLboolean fIsRenderbuffer (GLuint renderbuffer) {
-        BEFORE_GL_CALL;
-        realGLboolean retval = mSymbols.fIsRenderbuffer(renderbuffer);
+        realGLboolean retval = false;
+        BEFORE_GL_CALL;
+        retval = mSymbols.fIsRenderbuffer(renderbuffer);
         OnSyncCall();
         AFTER_GL_CALL;
         return retval;
     }
 
     void fRenderbufferStorage(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height) {
         BEFORE_GL_CALL;
         mSymbols.fRenderbufferStorage(target, internalFormat, width, height);
@@ -2079,44 +2079,48 @@ public:
         if (IsGLES()) {
             raw_fClearDepthf(v);
         } else {
             raw_fClearDepth(v);
         }
     }
 
     void* fMapBuffer(GLenum target, GLenum access) {
+        void* ret = nullptr;
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fMapBuffer);
-        void* ret = mSymbols.fMapBuffer(target, access);
+        ret = mSymbols.fMapBuffer(target, access);
         OnSyncCall();
         AFTER_GL_CALL;
         return ret;
     }
 
     realGLboolean fUnmapBuffer(GLenum target) {
+        realGLboolean ret = false;
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fUnmapBuffer);
-        realGLboolean ret = mSymbols.fUnmapBuffer(target);
+        ret = mSymbols.fUnmapBuffer(target);
         AFTER_GL_CALL;
         return ret;
     }
 
 
 private:
     GLuint raw_fCreateProgram() {
-        BEFORE_GL_CALL;
-        GLuint ret = mSymbols.fCreateProgram();
+        GLuint ret = 0;
+        BEFORE_GL_CALL;
+        ret = mSymbols.fCreateProgram();
         AFTER_GL_CALL;
         return ret;
     }
 
     GLuint raw_fCreateShader(GLenum t) {
-        BEFORE_GL_CALL;
-        GLuint ret = mSymbols.fCreateShader(t);
+        GLuint ret = 0;
+        BEFORE_GL_CALL;
+        ret = mSymbols.fCreateShader(t);
         AFTER_GL_CALL;
         return ret;
     }
 
     void raw_fGenBuffers(GLsizei n, GLuint* names) {
         BEFORE_GL_CALL;
         mSymbols.fGenBuffers(n, names);
         OnSyncCall();
@@ -2239,57 +2243,61 @@ public:
     }
 
     void fDeleteTextures(GLsizei n, const GLuint* names) {
         raw_fDeleteTextures(n, names);
         TRACKING_CONTEXT(DeletedTextures(this, n, names));
     }
 
     GLenum fGetGraphicsResetStatus() {
+        GLenum ret = 0;
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetGraphicsResetStatus);
-        GLenum ret = mSymbols.fGetGraphicsResetStatus();
+        ret = mSymbols.fGetGraphicsResetStatus();
         OnSyncCall();
         AFTER_GL_CALL;
         return ret;
     }
 
 
 // -----------------------------------------------------------------------------
 // Extension ARB_sync (GL)
 public:
     GLsync fFenceSync(GLenum condition, GLbitfield flags) {
+        GLsync ret = 0;
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fFenceSync);
-        GLsync ret = mSymbols.fFenceSync(condition, flags);
+        ret = mSymbols.fFenceSync(condition, flags);
         OnSyncCall();
         AFTER_GL_CALL;
         return ret;
     }
 
     realGLboolean fIsSync(GLsync sync) {
+        realGLboolean ret = false;
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fIsSync);
-        realGLboolean ret = mSymbols.fIsSync(sync);
+        ret = mSymbols.fIsSync(sync);
         OnSyncCall();
         AFTER_GL_CALL;
         return ret;
     }
 
     void fDeleteSync(GLsync sync) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fDeleteSync);
         mSymbols.fDeleteSync(sync);
         AFTER_GL_CALL;
     }
 
     GLenum fClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) {
+        GLenum ret = 0;
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fClientWaitSync);
-        GLenum ret = mSymbols.fClientWaitSync(sync, flags, timeout);
+        ret = mSymbols.fClientWaitSync(sync, flags, timeout);
         OnSyncCall();
         AFTER_GL_CALL;
         return ret;
     }
 
     void fWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fWaitSync);
@@ -2557,19 +2565,20 @@ public:
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fUniform4uiv);
         mSymbols.fUniform4uiv(location, count, value);
         AFTER_GL_CALL;
     }
 
     GLint fGetFragDataLocation(GLuint program, const GLchar* name)
     {
+        GLint result = 0;
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetFragDataLocation);
-        GLint result = mSymbols.fGetFragDataLocation(program, name);
+        result = mSymbols.fGetFragDataLocation(program, name);
         OnSyncCall();
         AFTER_GL_CALL;
         return result;
     }
 
 
 // -----------------------------------------------------------------------------
 // Package XXX_instanced_arrays
@@ -2654,19 +2663,20 @@ public:
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetQueryObjectuiv);
         mSymbols.fGetQueryObjectuiv(id, pname, params);
         OnSyncCall();
         AFTER_GL_CALL;
     }
 
     realGLboolean fIsQuery(GLuint query) {
+        realGLboolean retval = false;
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fIsQuery);
-        realGLboolean retval = mSymbols.fIsQuery(query);
+        retval = mSymbols.fIsQuery(query);
         OnSyncCall();
         AFTER_GL_CALL;
         return retval;
     }
 
 // -----------------------------------------------------------------------------
 // Package XXX_get_query_object_i64v
 /**
@@ -2746,19 +2756,20 @@ public:
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fDeleteTransformFeedbacks);
         mSymbols.fDeleteTransformFeedbacks(n, ids);
         AFTER_GL_CALL;
     }
 
     realGLboolean fIsTransformFeedback(GLuint id)
     {
+        realGLboolean result = false;
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fIsTransformFeedback);
-        realGLboolean result = mSymbols.fIsTransformFeedback(id);
+        result = mSymbols.fIsTransformFeedback(id);
         OnSyncCall();
         AFTER_GL_CALL;
         return result;
     }
 
     void fBindTransformFeedback(GLenum target, GLuint id)
     {
         BEFORE_GL_CALL;
@@ -2857,19 +2868,20 @@ public:
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGenVertexArrays);
         mSymbols.fGenVertexArrays(n, arrays);
         AFTER_GL_CALL;
     }
 
     realGLboolean fIsVertexArray(GLuint array)
     {
+        realGLboolean ret = false;
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fIsVertexArray);
-        realGLboolean ret = mSymbols.fIsVertexArray(array);
+        ret = mSymbols.fIsVertexArray(array);
         OnSyncCall();
         AFTER_GL_CALL;
         return ret;
     }
 
 // -----------------------------------------------------------------------------
 // Extension NV_fence
 public:
@@ -2894,38 +2906,40 @@ public:
         ASSERT_SYMBOL_PRESENT(fSetFence);
         BEFORE_GL_CALL;
         mSymbols.fSetFence(fence, condition);
         AFTER_GL_CALL;
     }
 
     realGLboolean fTestFence(GLuint fence)
     {
+        realGLboolean ret = false;
         ASSERT_SYMBOL_PRESENT(fTestFence);
         BEFORE_GL_CALL;
-        realGLboolean ret = mSymbols.fTestFence(fence);
+        ret = mSymbols.fTestFence(fence);
         OnSyncCall();
         AFTER_GL_CALL;
         return ret;
     }
 
     void fFinishFence(GLuint fence)
     {
         ASSERT_SYMBOL_PRESENT(fFinishFence);
         BEFORE_GL_CALL;
         mSymbols.fFinishFence(fence);
         OnSyncCall();
         AFTER_GL_CALL;
     }
 
     realGLboolean fIsFence(GLuint fence)
     {
+        realGLboolean ret = false;
         ASSERT_SYMBOL_PRESENT(fIsFence);
         BEFORE_GL_CALL;
-        realGLboolean ret = mSymbols.fIsFence(fence);
+        ret = mSymbols.fIsFence(fence);
         OnSyncCall();
         AFTER_GL_CALL;
         return ret;
     }
 
     void fGetFenceiv(GLuint fence, GLenum pname, GLint* params)
     {
         ASSERT_SYMBOL_PRESENT(fGetFenceiv);
@@ -2960,19 +2974,20 @@ public:
 
 
 // -----------------------------------------------------------------------------
 // Core GL & Extension ARB_map_buffer_range
 public:
     void* fMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length,
                           GLbitfield access)
     {
+        void* data = nullptr;
         ASSERT_SYMBOL_PRESENT(fMapBufferRange);
         BEFORE_GL_CALL;
-        void* data = mSymbols.fMapBufferRange(target, offset, length, access);
+        data = mSymbols.fMapBufferRange(target, offset, length, access);
         OnSyncCall();
         AFTER_GL_CALL;
         return data;
     }
 
     void fFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) {
         ASSERT_SYMBOL_PRESENT(fFlushMappedBufferRange);
         BEFORE_GL_CALL;
@@ -2997,19 +3012,20 @@ public:
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fDeleteSamplers);
         mSymbols.fDeleteSamplers(count, samplers);
         AFTER_GL_CALL;
     }
 
     realGLboolean fIsSampler(GLuint sampler)
     {
+        realGLboolean result = false;
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fIsSampler);
-        realGLboolean result = mSymbols.fIsSampler(sampler);
+        result = mSymbols.fIsSampler(sampler);
         OnSyncCall();
         AFTER_GL_CALL;
         return result;
     }
 
     void fBindSampler(GLuint unit, GLuint sampler)
     {
         BEFORE_GL_CALL;
@@ -3086,19 +3102,20 @@ public:
         ASSERT_SYMBOL_PRESENT(fGetActiveUniformsiv);
         BEFORE_GL_CALL;
         mSymbols.fGetActiveUniformsiv(program, uniformCount, uniformIndices, pname, params);
         OnSyncCall();
         AFTER_GL_CALL;
     }
 
     GLuint fGetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName) {
+        GLuint result = 0;
         ASSERT_SYMBOL_PRESENT(fGetUniformBlockIndex);
         BEFORE_GL_CALL;
-        GLuint result = mSymbols.fGetUniformBlockIndex(program, uniformBlockName);
+        result = mSymbols.fGetUniformBlockIndex(program, uniformBlockName);
         OnSyncCall();
         AFTER_GL_CALL;
         return result;
     }
 
     void fGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex,
                                   GLenum pname, GLint* params)
     {
@@ -3215,19 +3232,20 @@ public:
                                           format, imageSize, data);
         AFTER_GL_CALL;
     }
 
 // -----------------------------------------------------------------------------
 // GL3+, ES3+
 
     const GLubyte* fGetStringi(GLenum name, GLuint index) {
+        const GLubyte* ret = nullptr;
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetStringi);
-        const GLubyte* ret = mSymbols.fGetStringi(name, index);
+        ret = mSymbols.fGetStringi(name, index);
         OnSyncCall();
         AFTER_GL_CALL;
         return ret;
     }
 
 // -----------------------------------------------------------------------------
 // APPLE_framebuffer_multisample
 
@@ -3243,16 +3261,22 @@ public:
 
     void fPrimitiveRestartIndex(GLuint index) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fPrimitiveRestartIndex);
         mSymbols.fPrimitiveRestartIndex(index);
         AFTER_GL_CALL;
     }
 
+#undef BEFORE_GL_CALL
+#undef AFTER_GL_CALL
+#undef ASSERT_SYMBOL_PRESENT
+// #undef TRACKING_CONTEXT // Needed in GLContext.cpp
+#undef ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL
+
 // -----------------------------------------------------------------------------
 // Constructor
 protected:
     explicit GLContext(CreateContextFlags flags, const SurfaceCaps& caps,
                        GLContext* sharedContext = nullptr,
                        bool isOffscreen = false, bool canUseTLSIsCurrent = false);
 
 
@@ -3588,35 +3612,16 @@ protected:
     }
 
 
 public:
     GLsizei MaxSamples() const {
         return mMaxSamples;
     }
 
-    void fViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
-        if (mViewportRect[0] == x &&
-            mViewportRect[1] == y &&
-            mViewportRect[2] == width &&
-            mViewportRect[3] == height)
-        {
-            return;
-        }
-        mViewportRect[0] = x;
-        mViewportRect[1] = y;
-        mViewportRect[2] = width;
-        mViewportRect[3] = height;
-        BEFORE_GL_CALL;
-        mSymbols.fViewport(x, y, width, height);
-        AFTER_GL_CALL;
-    }
-
-#undef ASSERT_SYMBOL_PRESENT
-
 #ifdef MOZ_GL_DEBUG
     void CreatedProgram(GLContext* aOrigin, GLuint aName);
     void CreatedShader(GLContext* aOrigin, GLuint aName);
     void CreatedBuffers(GLContext* aOrigin, GLsizei aCount, GLuint* aNames);
     void CreatedQueries(GLContext* aOrigin, GLsizei aCount, GLuint* aNames);
     void CreatedTextures(GLContext* aOrigin, GLsizei aCount, GLuint* aNames);
     void CreatedFramebuffers(GLContext* aOrigin, GLsizei aCount, GLuint* aNames);
     void CreatedRenderbuffers(GLContext* aOrigin, GLsizei aCount, GLuint* aNames);