Bug 736481 - 2/7 - lose WebGL context on memory-pressure events - r=jgilbert, a=blocking-fennec
authorBenoit Jacob <bjacob@mozilla.com>
Sat, 21 Apr 2012 16:48:22 -0400
changeset 95392 9528f37307f3788463f8f59bce0a6e0b63b72088
parent 95391 bd7c35f578061e4ca1adb20f389def117c4b7b4d
child 95393 ac74798eb3d3741b7b0e0b05ef0c63d68596647c
push id886
push userlsblakk@mozilla.com
push dateMon, 04 Jun 2012 19:57:52 +0000
treeherdermozilla-beta@bbd8d5efd6d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjgilbert, blocking-fennec
bugs736481
milestone14.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 736481 - 2/7 - lose WebGL context on memory-pressure events - r=jgilbert, a=blocking-fennec
content/canvas/src/WebGLContext.cpp
content/canvas/src/WebGLContext.h
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -66,20 +66,35 @@
 
 #include "nsSVGEffects.h"
 
 #include "prenv.h"
 
 #include "mozilla/Preferences.h"
 #include "mozilla/Telemetry.h"
 
+#include "nsIObserverService.h"
+
+
 using namespace mozilla;
 using namespace mozilla::gl;
 using namespace mozilla::layers;
 
+NS_IMPL_ISUPPORTS1(WebGLMemoryPressureObserver, nsIObserver)
+
+NS_IMETHODIMP
+WebGLMemoryPressureObserver::Observe(nsISupports* aSubject,
+                                     const char* aTopic,
+                                     const PRUnichar* aSomeData)
+{
+  if (strcmp(aTopic, "memory-pressure") == 0)
+    mContext->ForceLoseContext();
+  return NS_OK;
+}
+
 
 nsresult NS_NewCanvasRenderingContextWebGL(nsIDOMWebGLRenderingContext** aResult);
 
 nsresult
 NS_NewCanvasRenderingContextWebGL(nsIDOMWebGLRenderingContext** aResult)
 {
     Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_USED, 1);
     nsIDOMWebGLRenderingContext* ctx = new WebGLContext();
@@ -167,16 +182,26 @@ WebGLContext::WebGLContext()
     WebGLMemoryMultiReporterWrapper::AddWebGLContext(this);
 
     mAllowRestore = true;
     mRobustnessTimerRunning = false;
     mDrawSinceRobustnessTimerSet = false;
     mContextRestorer = do_CreateInstance("@mozilla.org/timer;1");
     mContextStatus = ContextStable;
     mContextLostErrorSet = false;
+
+    nsRefPtr<WebGLMemoryPressureObserver> memoryPressureObserver
+        = new WebGLMemoryPressureObserver(this);
+    nsCOMPtr<nsIObserverService> observerService
+        = mozilla::services::GetObserverService();
+    if (observerService) {
+        observerService->AddObserver(memoryPressureObserver,
+                                     "memory-pressure",
+                                     false);
+    }
 }
 
 WebGLContext::~WebGLContext()
 {
     DestroyResourcesAndContext();
     WebGLMemoryMultiReporterWrapper::RemoveWebGLContext(this);
     TerminateRobustnessTimer();
     mContextRestorer = nsnull;
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -54,16 +54,17 @@
 #include "nsICanvasRenderingContextInternal.h"
 #include "nsHTMLCanvasElement.h"
 #include "nsWeakReference.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIMemoryReporter.h"
 #include "nsIJSNativeInitializer.h"
 #include "nsContentUtils.h"
 #include "nsWrapperCache.h"
+#include "nsIObserver.h"
 
 #include "GLContextProvider.h"
 #include "Layers.h"
 
 #include "CheckedInt.h"
 #include "nsDataHashtable.h"
 
 #ifdef XP_MACOSX
@@ -521,16 +522,17 @@ class WebGLContext :
     public nsICanvasRenderingContextInternal,
     public nsSupportsWeakReference,
     public nsITimerCallback,
     public WebGLRectangleObject
 {
     friend class WebGLMemoryMultiReporterWrapper;
     friend class WebGLExtensionLoseContext;
     friend class WebGLContextUserData;
+    friend class WebGLMemoryPressureObserver;
 
 public:
     WebGLContext();
     virtual ~WebGLContext();
 
     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
     NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(WebGLContext, nsIDOMWebGLRenderingContext)
@@ -2882,11 +2884,26 @@ class WebGLMemoryMultiReporterWrapper
         return result;
     }
 
     static PRInt64 GetContextCount() {
         return Contexts().Length();
     }
 };
 
+class WebGLMemoryPressureObserver MOZ_FINAL
+    : public nsIObserver
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIOBSERVER
+
+  WebGLMemoryPressureObserver(WebGLContext *context)
+    : mContext(context)
+  {}
+
+private:
+  WebGLContext *mContext;
+};
+
 }
 
 #endif