Implement preferLowPowerToHighPerformance for WebGL
authordino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 19 Aug 2016 22:52:24 +0000 (22:52 +0000)
committerdino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 19 Aug 2016 22:52:24 +0000 (22:52 +0000)
https://bugs.webkit.org/show_bug.cgi?id=161017
<rdar://problem/26819135>

Reviewed by Myles Maxfield.

.:

A manual test that creates contexts with and without preferLowPowerToHighPerformance
to see what is used. This has to be manual because it depends on the hardware
configuration, and we don't have a way to detect it up-front. Also, if the
code was failing, it would be the same result as on a single GPU system.

* ManualTests/webgl-preferLowPowerToHighPerformance.html: Added.

Source/WebCore:

Implement preferLowPowerToHighPerformance on macOS by
passing the correct CGL attribute when creating the
pixel format.

* bindings/js/JSHTMLCanvasElementCustom.cpp:
(WebCore::get3DContextAttributes):
* platform/graphics/mac/GraphicsContext3DMac.mm:
(WebCore::setPixelFormat):
(WebCore::GraphicsContext3D::GraphicsContext3D):

LayoutTests:

Now that we implement preferLowPowerToHighPerformance we can
retain its value in the context creation attributes object.

* fast/canvas/webgl/context-creation-attributes-expected.txt:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@204664 268f45cc-cd09-0410-ab3c-d52691b4dbfc

ChangeLog
LayoutTests/ChangeLog
LayoutTests/fast/canvas/webgl/context-creation-attributes-expected.txt
ManualTests/webgl-preferLowPowerToHighPerformance.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/JSHTMLCanvasElementCustom.cpp
Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm

index 7256bce..9081b9f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2016-08-19  Dean Jackson  <dino@apple.com>
+
+        Implement preferLowPowerToHighPerformance for WebGL
+        https://bugs.webkit.org/show_bug.cgi?id=161017
+        <rdar://problem/26819135>
+
+        Reviewed by Myles Maxfield.
+
+        A manual test that creates contexts with and without preferLowPowerToHighPerformance
+        to see what is used. This has to be manual because it depends on the hardware
+        configuration, and we don't have a way to detect it up-front. Also, if the
+        code was failing, it would be the same result as on a single GPU system.
+
+        * ManualTests/webgl-preferLowPowerToHighPerformance.html: Added.
+
 2016-08-19  Per Arne Vollan  <pvollan@apple.com>
 
         [Win] Warning fix.
index f0cae6c..38ba335 100644 (file)
@@ -1,3 +1,16 @@
+2016-08-19  Dean Jackson  <dino@apple.com>
+
+        Implement preferLowPowerToHighPerformance for WebGL
+        https://bugs.webkit.org/show_bug.cgi?id=161017
+        <rdar://problem/26819135>
+
+        Reviewed by Myles Maxfield.
+
+        Now that we implement preferLowPowerToHighPerformance we can
+        retain its value in the context creation attributes object.
+
+        * fast/canvas/webgl/context-creation-attributes-expected.txt:
+
 2016-08-19  Ryan Haddad  <ryanhaddad@apple.com>
 
         Rebaseline imported/w3c/web-platform-tests/html/semantics/interfaces.html for ios-simulator after r204647.
index d02b2b2..7ed4c2c 100644 (file)
@@ -2,5 +2,5 @@ Note that some of the values tested here might not be supported, and thus should
 
 {"alpha":true,"depth":true,"stencil":false,"antialias":true,"premultipliedAlpha":true,"preserveDrawingBuffer":false,"preferLowPowerToHighPerformance":false,"failIfMajorPerformanceCaveat":false}
 {"alpha":true,"depth":true,"stencil":true,"antialias":true,"premultipliedAlpha":true,"preserveDrawingBuffer":false,"preferLowPowerToHighPerformance":false,"failIfMajorPerformanceCaveat":false}
-{"alpha":true,"depth":true,"stencil":false,"antialias":true,"premultipliedAlpha":true,"preserveDrawingBuffer":false,"preferLowPowerToHighPerformance":false,"failIfMajorPerformanceCaveat":false}
+{"alpha":true,"depth":true,"stencil":false,"antialias":true,"premultipliedAlpha":true,"preserveDrawingBuffer":false,"preferLowPowerToHighPerformance":true,"failIfMajorPerformanceCaveat":false}
 {"alpha":true,"depth":true,"stencil":false,"antialias":true,"premultipliedAlpha":true,"preserveDrawingBuffer":false,"preferLowPowerToHighPerformance":false,"failIfMajorPerformanceCaveat":false}
diff --git a/ManualTests/webgl-preferLowPowerToHighPerformance.html b/ManualTests/webgl-preferLowPowerToHighPerformance.html
new file mode 100644 (file)
index 0000000..2e96b06
--- /dev/null
@@ -0,0 +1,38 @@
+<script>
+function createAndDescribeContext(msg, parameters)
+{
+    var canvas = document.createElement("canvas");
+    var gl = canvas.getContext("webgl", parameters);
+    var ext = gl.getExtension("WEBGL_debug_renderer_info");
+
+    var header = document.createElement("p");
+    header.textContent = msg;
+    document.body.appendChild(header);
+
+    var result = document.createElement("pre");
+    result.textContent = "UNMASKED_VENDOR_WEBGL is " + gl.getParameter(ext.UNMASKED_VENDOR_WEBGL) + "\n";
+    result.textContent += "UNMASKED_RENDERER_WEBGL is " + gl.getParameter(ext.UNMASKED_RENDERER_WEBGL);
+    document.body.appendChild(result);
+}
+
+function run()
+{
+    createAndDescribeContext("With preferLowPowerToHighPerformance", {preferLowPowerToHighPerformance: true});
+    createAndDescribeContext("Without preferLowPowerToHighPerformance", {});
+}
+
+window.addEventListener("load", run, false);
+</script>
+<p>
+    This is a manual test, since it relies on hardware configurations. It creates two
+    WebGL contexts. It first asks for a context with preferLowPowerToHighPerformance
+    set to true, and then for a context with the default value (false).
+</p>
+<p>
+    Unfortunately there isn't a completely reliable way to know if this test passed.
+    On a system with both an integrated and discrete GPU, assuming that the system
+    is configured to prefer the integrated GPU, and no other apps are running
+    that might cause the discrete GPU to be active, the two renderers should be different.
+    Also, if they are different, then the first one should be the lower power model
+    (i.e. the integrated card).
+</p>
\ No newline at end of file
index e9821c8..60fb4c6 100644 (file)
@@ -1,3 +1,21 @@
+2016-08-19  Dean Jackson  <dino@apple.com>
+
+        Implement preferLowPowerToHighPerformance for WebGL
+        https://bugs.webkit.org/show_bug.cgi?id=161017
+        <rdar://problem/26819135>
+
+        Reviewed by Myles Maxfield.
+
+        Implement preferLowPowerToHighPerformance on macOS by
+        passing the correct CGL attribute when creating the
+        pixel format.
+
+        * bindings/js/JSHTMLCanvasElementCustom.cpp:
+        (WebCore::get3DContextAttributes):
+        * platform/graphics/mac/GraphicsContext3DMac.mm:
+        (WebCore::setPixelFormat):
+        (WebCore::GraphicsContext3D::GraphicsContext3D):
+
 2016-08-19  Joseph Pecoraro  <pecoraro@apple.com>
 
         Remove empty files and empty namespace blocks
index 77eee5c..4c81179 100644 (file)
@@ -62,7 +62,8 @@ static void get3DContextAttributes(ExecState& state, RefPtr<CanvasContextAttribu
     dictionary.tryGetProperty("antialias", graphicsAttrs.antialias);
     dictionary.tryGetProperty("premultipliedAlpha", graphicsAttrs.premultipliedAlpha);
     dictionary.tryGetProperty("preserveDrawingBuffer", graphicsAttrs.preserveDrawingBuffer);
-    
+    dictionary.tryGetProperty("preferLowPowerToHighPerformance", graphicsAttrs.preferLowPowerToHighPerformance);
+
     attrs = WebGLContextAttributes::create(graphicsAttrs);
 }
 #endif
index 37d49d1..75f6852 100644 (file)
@@ -84,7 +84,7 @@ public:
 };
 
 #if !PLATFORM(IOS)
-static void setPixelFormat(Vector<CGLPixelFormatAttribute>& attribs, int colorBits, int depthBits, bool accelerated, bool supersample, bool closest, bool antialias)
+static void setPixelFormat(Vector<CGLPixelFormatAttribute>& attribs, int colorBits, int depthBits, bool accelerated, bool supersample, bool closest, bool antialias, bool allowOffline)
 {
     attribs.clear();
     
@@ -92,7 +92,14 @@ static void setPixelFormat(Vector<CGLPixelFormatAttribute>& attribs, int colorBi
     attribs.append(static_cast<CGLPixelFormatAttribute>(colorBits));
     attribs.append(kCGLPFADepthSize);
     attribs.append(static_cast<CGLPixelFormatAttribute>(depthBits));
-    
+
+    // This attribute, while mentioning offline renderers, is actually
+    // allowing us to request the integrated graphics on a dual GPU
+    // system, and not force the discrete GPU.
+    // See https://developer.apple.com/library/mac/technotes/tn2229/_index.html
+    if (allowOffline)
+        attribs.append(kCGLPFAAllowOfflineRenderers);
+
     if (accelerated)
         attribs.append(kCGLPFAAccelerated);
     else {
@@ -191,22 +198,22 @@ GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWi
     // If none of that works, we simply fail and set m_contextObj to 0.
 
     bool useMultisampling = m_attrs.antialias;
-    
-    setPixelFormat(attribs, 32, 32, !attrs.forceSoftwareRenderer, true, false, useMultisampling);
+
+    setPixelFormat(attribs, 32, 32, !attrs.forceSoftwareRenderer, true, false, useMultisampling, attrs.preferLowPowerToHighPerformance);
     CGLChoosePixelFormat(attribs.data(), &pixelFormatObj, &numPixelFormats);
 
-    if (numPixelFormats == 0) {
-        setPixelFormat(attribs, 32, 32, !attrs.forceSoftwareRenderer, false, false, useMultisampling);
+    if (!numPixelFormats) {
+        setPixelFormat(attribs, 32, 32, !attrs.forceSoftwareRenderer, false, false, useMultisampling, attrs.preferLowPowerToHighPerformance);
         CGLChoosePixelFormat(attribs.data(), &pixelFormatObj, &numPixelFormats);
 
-        if (numPixelFormats == 0) {
-            setPixelFormat(attribs, 32, 16, !attrs.forceSoftwareRenderer, false, false, useMultisampling);
+        if (!numPixelFormats) {
+            setPixelFormat(attribs, 32, 16, !attrs.forceSoftwareRenderer, false, false, useMultisampling, attrs.preferLowPowerToHighPerformance);
             CGLChoosePixelFormat(attribs.data(), &pixelFormatObj, &numPixelFormats);
 
-             if (!attrs.forceSoftwareRenderer && numPixelFormats == 0) {
-                 setPixelFormat(attribs, 32, 16, false, false, true, false);
-                 CGLChoosePixelFormat(attribs.data(), &pixelFormatObj, &numPixelFormats);
-                 useMultisampling = false;
+            if (!attrs.forceSoftwareRenderer && !numPixelFormats) {
+                setPixelFormat(attribs, 32, 16, false, false, true, false, false);
+                CGLChoosePixelFormat(attribs.data(), &pixelFormatObj, &numPixelFormats);
+                useMultisampling = false;
             }
         }
     }