Bug 713305 - Force staying on discrete GPU while any WebGL context is live - r=jrmuizel
authorBenoit Jacob <bjacob@mozilla.com>
Wed, 29 Feb 2012 15:49:55 -0500
changeset 87955 1c3b291d08306cf3535e1a1f262ce8567f99e218
parent 87954 3812d0ce274e8ad01f579efcd2dffd4d83be0295
child 87956 7672adec56b9b5e28367d781f4042c45fb818473
push idunknown
push userunknown
push dateunknown
reviewersjrmuizel
bugs713305
milestone13.0a1
first release with
nightly linux32
1c3b291d0830 / 13.0a1 / 20120301031135 / files
nightly linux64
1c3b291d0830 / 13.0a1 / 20120301031135 / files
nightly mac
1c3b291d0830 / 13.0a1 / 20120301031135 / files
nightly win32
1c3b291d0830 / 13.0a1 / 20120301031135 / files
nightly win64
1c3b291d0830 / 13.0a1 / 20120301031135 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 713305 - Force staying on discrete GPU while any WebGL context is live - r=jrmuizel
content/canvas/src/WebGLContext.h
gfx/gl/ForceDiscreteGPUHelperCGL.h
gfx/gl/Makefile.in
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -59,16 +59,20 @@
 #include "nsIJSNativeInitializer.h"
 #include "nsContentUtils.h"
 
 #include "GLContextProvider.h"
 #include "Layers.h"
 
 #include "CheckedInt.h"
 
+#ifdef XP_MACOSX
+#include "ForceDiscreteGPUHelperCGL.h"
+#endif
+
 /* 
  * Minimum value constants defined in 6.2 State Tables of OpenGL ES - 2.0.25
  *   https://bugzilla.mozilla.org/show_bug.cgi?id=686732
  * 
  * Exceptions: some of the following values are set to higher values than in the spec because
  * the values in the spec are ridiculously low. They are explicitly marked below
 */
 #define MINVALUE_GL_MAX_TEXTURE_SIZE                  1024  // Different from the spec, which sets it to 64 on page 162
@@ -938,16 +942,26 @@ protected:
     nsCOMPtr<nsITimer> mContextRestorer;
     bool mAllowRestore;
     bool mRobustnessTimerRunning;
     bool mDrawSinceRobustnessTimerSet;
     ContextStatus mContextStatus;
     bool mContextLostErrorSet;
     bool mContextLostDueToTest;
 
+#ifdef XP_MACOSX
+    // see bug 713305. This RAII helper guarantees that we're on the discrete GPU, during its lifetime
+    // Debouncing note: we don't want to switch GPUs too frequently, so try to not create and destroy
+    // these objects at high frequency. Having WebGLContext's hold one such object seems fine,
+    // because WebGLContext objects only go away during GC, which shouldn't happen too frequently.
+    // If in the future GC becomes much more frequent, we may have to revisit then (maybe use a timer).
+    ForceDiscreteGPUHelperCGL mForceDiscreteGPUHelper;
+#endif
+
+
 public:
     // console logging helpers
     static void LogMessage(const char *fmt, ...);
     static void LogMessage(const char *fmt, va_list ap);
     void LogMessageIfVerbose(const char *fmt, ...);
     void LogMessageIfVerbose(const char *fmt, va_list ap);
 
     friend class WebGLTexture;
new file mode 100644
--- /dev/null
+++ b/gfx/gl/ForceDiscreteGPUHelperCGL.h
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef ForceDiscreteGPUHelperCGL_h_
+#define ForceDiscreteGPUHelperCGL_h_
+
+#include <OpenGL/OpenGL.h>
+
+/** This RAII helper guarantees that we're on the discrete GPU during its lifetime.
+ * 
+ * As long as any ForceDiscreteGPUHelperCGL object is alive, we're on the discrete GPU.
+ */
+class ForceDiscreteGPUHelperCGL
+{
+    CGLPixelFormatObj mPixelFormatObj;
+
+public:
+    ForceDiscreteGPUHelperCGL()
+    {
+        // the code in this function is taken from Chromium, src/ui/gfx/gl/gl_context_cgl.cc, r122013
+        // BSD-style license, (c) The Chromium Authors
+        CGLPixelFormatAttribute attribs[1];
+        attribs[0] = static_cast<CGLPixelFormatAttribute>(0);
+        GLint num_pixel_formats = 0;
+        CGLChoosePixelFormat(attribs, &mPixelFormatObj, &num_pixel_formats);
+    }
+
+    ~ForceDiscreteGPUHelperCGL()
+    {
+        CGLReleasePixelFormat(mPixelFormatObj);
+    }
+};
+
+#endif // ForceDiscreteGPUHelperCGL_h_
--- a/gfx/gl/Makefile.in
+++ b/gfx/gl/Makefile.in
@@ -47,16 +47,17 @@ EXPORT_LIBRARY	= 1
 
 EXPORTS	= \
 	GLDefs.h \
 	GLContext.h \
 	GLContextSymbols.h \
 	GLContextProvider.h \
 	GLContextProviderImpl.h \
 	EGLUtils.h \
+	ForceDiscreteGPUHelperCGL.h \
 	$(NULL)
 
 ifdef MOZ_X11
 EXPORTS += \
 	GLXLibrary.h \
 	$(NULL)
 endif