Bug 982464 - Disable extension functionality after a context lost happens. r=jgilbert
authorDan Glastonbury <dglastonbury@mozilla.com>
Wed, 12 Mar 2014 12:51:39 +1000
changeset 190867 cef5e324878788d2d31722b19fda612fb7b37612
parent 190866 3719528f82525aece9f62148f54fb02ca3020f1b
child 190868 a25a6bf64a5f048c0c677094478fc2ec99340911
push id3503
push userraliiev@mozilla.com
push dateMon, 28 Apr 2014 18:51:11 +0000
treeherdermozilla-beta@c95ac01e332e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjgilbert
bugs982464
milestone30.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 982464 - Disable extension functionality after a context lost happens. r=jgilbert
content/canvas/src/WebGLContext.cpp
content/canvas/src/WebGLExtensionBase.cpp
content/canvas/src/WebGLExtensionDebugShaders.cpp
content/canvas/src/WebGLExtensionDrawBuffers.cpp
content/canvas/src/WebGLExtensionInstancedArrays.cpp
content/canvas/src/WebGLExtensionVertexArray.cpp
content/canvas/src/WebGLExtensions.h
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -282,16 +282,17 @@ WebGLContext::DestroyResourcesAndContext
     // disable all extensions except "WEBGL_lose_context". see bug #927969
     // spec: http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
     for (size_t i = 0; i < size_t(WebGLExtensionID_max); ++i) {
         WebGLExtensionID extension = WebGLExtensionID(i);
 
         if (!IsExtensionEnabled(extension) || (extension == WEBGL_lose_context))
             continue;
 
+        mExtensions[extension]->MarkLost();
         mExtensions[extension] = nullptr;
     }
 
     // We just got rid of everything, so the context had better
     // have been going away.
 #ifdef DEBUG
     if (gl->DebugMode()) {
         printf_stderr("--- WebGL context destroyed: %p\n", gl.get());
--- a/content/canvas/src/WebGLExtensionBase.cpp
+++ b/content/canvas/src/WebGLExtensionBase.cpp
@@ -5,20 +5,27 @@
 
 #include "WebGLContext.h"
 #include "WebGLExtensions.h"
 
 using namespace mozilla;
 
 WebGLExtensionBase::WebGLExtensionBase(WebGLContext* context)
     : WebGLContextBoundObject(context)
+    , mIsLost(false)
 {
     SetIsDOMBinding();
 }
 
 WebGLExtensionBase::~WebGLExtensionBase()
 {
 }
 
+void
+WebGLExtensionBase::MarkLost()
+{
+    mIsLost = true;
+}
+
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLExtensionBase)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLExtensionBase, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLExtensionBase, Release)
--- a/content/canvas/src/WebGLExtensionDebugShaders.cpp
+++ b/content/canvas/src/WebGLExtensionDebugShaders.cpp
@@ -21,16 +21,21 @@ WebGLExtensionDebugShaders::~WebGLExtens
 /* If no source has been defined, compileShader() has not been called,
  * or the translation has failed for shader, an empty string is
  * returned; otherwise, return the translated source.
  */
 void
 WebGLExtensionDebugShaders::GetTranslatedShaderSource(WebGLShader* shader,
                                                       nsAString& retval)
 {
+    if (mIsLost) {
+        return mContext->ErrorInvalidOperation("getTranslatedShaderSource: "
+                                               "Extension is lost.");
+    }
+
     mContext->GetShaderTranslatedSource(shader, retval);
 
     if (retval.IsVoid()) {
         CopyASCIItoUTF16("", retval);
     }
 }
 
 IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionDebugShaders)
--- a/content/canvas/src/WebGLExtensionDrawBuffers.cpp
+++ b/content/canvas/src/WebGLExtensionDrawBuffers.cpp
@@ -1,8 +1,9 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WebGLContext.h"
 #include "WebGLExtensions.h"
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
 #include "WebGLTexture.h"
@@ -44,16 +45,19 @@ WebGLExtensionDrawBuffers::WebGLExtensio
 }
 
 WebGLExtensionDrawBuffers::~WebGLExtensionDrawBuffers()
 {
 }
 
 void WebGLExtensionDrawBuffers::DrawBuffersWEBGL(const dom::Sequence<GLenum>& buffers)
 {
+    if (mIsLost)
+        return mContext->ErrorInvalidOperation("drawBuffersWEBGL: Extension is lost.");
+
     mContext->DrawBuffers(buffers);
 }
 
 bool WebGLExtensionDrawBuffers::IsSupported(const WebGLContext* context)
 {
     gl::GLContext * gl = context->GL();
 
     if (!gl->IsSupported(GLFeature::draw_buffers)) {
--- a/content/canvas/src/WebGLExtensionInstancedArrays.cpp
+++ b/content/canvas/src/WebGLExtensionInstancedArrays.cpp
@@ -20,30 +20,39 @@ WebGLExtensionInstancedArrays::WebGLExte
 WebGLExtensionInstancedArrays::~WebGLExtensionInstancedArrays()
 {
 }
 
 void
 WebGLExtensionInstancedArrays::DrawArraysInstancedANGLE(GLenum mode, GLint first,
                                                         GLsizei count, GLsizei primcount)
 {
+    if (mIsLost)
+        return mContext->ErrorInvalidOperation("drawArraysInstancedANGLE: Extension is lost.");
+
     mContext->DrawArraysInstanced(mode, first, count, primcount);
 }
 
 void
 WebGLExtensionInstancedArrays::DrawElementsInstancedANGLE(GLenum mode, GLsizei count,
                                                           GLenum type, WebGLintptr offset,
                                                           GLsizei primcount)
 {
+    if (mIsLost)
+        return mContext->ErrorInvalidOperation("drawElementsInstancedANGLE: Extension is lost.");
+
     mContext->DrawElementsInstanced(mode, count, type, offset, primcount);
 }
 
 void
 WebGLExtensionInstancedArrays::VertexAttribDivisorANGLE(GLuint index, GLuint divisor)
 {
+    if (mIsLost)
+        return mContext->ErrorInvalidOperation("vertexAttribDivisorANGLE: Extension is lost.");
+
     mContext->VertexAttribDivisor(index, divisor);
 }
 
 bool
 WebGLExtensionInstancedArrays::IsSupported(const WebGLContext* context)
 {
     gl::GLContext* gl = context->GL();
 
--- a/content/canvas/src/WebGLExtensionVertexArray.cpp
+++ b/content/canvas/src/WebGLExtensionVertexArray.cpp
@@ -20,31 +20,47 @@ WebGLExtensionVertexArray::WebGLExtensio
 }
 
 WebGLExtensionVertexArray::~WebGLExtensionVertexArray()
 {
 }
 
 already_AddRefed<WebGLVertexArray> WebGLExtensionVertexArray::CreateVertexArrayOES()
 {
+    if (mIsLost) {
+        mContext->ErrorInvalidOperation("createVertexArrayOES: Extension is lost. Returning NULL.");
+        return nullptr;
+    }
+
     return mContext->CreateVertexArray();
 }
 
 void WebGLExtensionVertexArray::DeleteVertexArrayOES(WebGLVertexArray* array)
 {
+    if (mIsLost)
+        return mContext->ErrorInvalidOperation("deleteVertexArrayOES: Extension is lost.");
+
     mContext->DeleteVertexArray(array);
 }
 
 bool WebGLExtensionVertexArray::IsVertexArrayOES(WebGLVertexArray* array)
 {
+    if (mIsLost) {
+        mContext->ErrorInvalidOperation("isVertexArrayOES: Extension is lost. Returning false.");
+        return false;
+    }
+
     return mContext->IsVertexArray(array);
 }
 
 void WebGLExtensionVertexArray::BindVertexArrayOES(WebGLVertexArray* array)
 {
+    if (mIsLost)
+        return mContext->ErrorInvalidOperation("bindVertexArrayOES: Extension is lost.");
+
     mContext->BindVertexArray(array);
 }
 
 bool WebGLExtensionVertexArray::IsSupported(const WebGLContext* context)
 {
     gl::GLContext* gl = context->GL();
 
     return gl->IsSupported(gl::GLFeature::vertex_array_object);
--- a/content/canvas/src/WebGLExtensions.h
+++ b/content/canvas/src/WebGLExtensions.h
@@ -25,18 +25,23 @@ class WebGLExtensionBase
 public:
     WebGLExtensionBase(WebGLContext*);
     virtual ~WebGLExtensionBase();
 
     WebGLContext *GetParentObject() const {
         return Context();
     }
 
+    void MarkLost();
+
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLExtensionBase)
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLExtensionBase)
+
+protected:
+    bool mIsLost;
 };
 
 #define DECL_WEBGL_EXTENSION_GOOP                                           \
     virtual JSObject* WrapObject(JSContext *cx,                             \
                                  JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
 
 #define IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionType) \
     JSObject* \