<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[211028] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/211028">211028</a></dd>
<dt>Author</dt> <dd>dino@apple.com</dd>
<dt>Date</dt> <dd>2017-01-22 10:51:09 -0800 (Sun, 22 Jan 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>[WebGL] Do not allow GPU muxing on some old Mac hardware
https://bugs.webkit.org/show_bug.cgi?id=167259
&lt;rdar://problem/30060378&gt;

Reviewed by Simon Fraser and Darin Adler.

Some old Macbook Pro models should never use the
integrated GPU for WebGL, because they are unstable
when swapping between that and the discrete GPU.

Unfortunately this hardware configuration isn't in our
testing infrastructure, so it was confirmed manually.
Meanwhile, our existing tests make sure this patch
doesn't break anything elsewhere.

* platform/graphics/mac/GraphicsContext3DMac.mm:
(WebCore::attachToAppleGraphicsControl): Helper function
to get a mach port that talks to Apple's Graphics Control
system.
(WebCore::hasMuxCapability): Decides whether a system
can do live GPU switching, based on whether or not it
has a muxable GPU, and if that GPU is not the old hardware
we know is problematic.
(WebCore::hasMuxableGPU): Helper to return the static hasMuxCapability value.
(WebCore::setPixelFormat): Only request the integrated card when the
GPU is muxable.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsmacGraphicsContext3DMacmm">trunk/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (211027 => 211028)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2017-01-22 17:24:51 UTC (rev 211027)
+++ trunk/Source/WebCore/ChangeLog        2017-01-22 18:51:09 UTC (rev 211028)
</span><span class="lines">@@ -1,3 +1,32 @@
</span><ins>+2017-01-20  Dean Jackson  &lt;dino@apple.com&gt;
+
+        [WebGL] Do not allow GPU muxing on some old Mac hardware
+        https://bugs.webkit.org/show_bug.cgi?id=167259
+        &lt;rdar://problem/30060378&gt;
+
+        Reviewed by Simon Fraser and Darin Adler.
+
+        Some old Macbook Pro models should never use the
+        integrated GPU for WebGL, because they are unstable
+        when swapping between that and the discrete GPU.
+
+        Unfortunately this hardware configuration isn't in our
+        testing infrastructure, so it was confirmed manually.
+        Meanwhile, our existing tests make sure this patch
+        doesn't break anything elsewhere.
+
+        * platform/graphics/mac/GraphicsContext3DMac.mm:
+        (WebCore::attachToAppleGraphicsControl): Helper function
+        to get a mach port that talks to Apple's Graphics Control
+        system.
+        (WebCore::hasMuxCapability): Decides whether a system
+        can do live GPU switching, based on whether or not it
+        has a muxable GPU, and if that GPU is not the old hardware
+        we know is problematic.
+        (WebCore::hasMuxableGPU): Helper to return the static hasMuxCapability value.
+        (WebCore::setPixelFormat): Only request the integrated card when the
+        GPU is muxable.
+
</ins><span class="cx"> 2017-01-22  Don Olmstead &lt;don.olmstead@am.sony.com&gt; and Myles C. Maxfield &lt;mmaxfield@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Introducing the Platform Abstraction Layer (PAL)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsmacGraphicsContext3DMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm (211027 => 211028)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm        2017-01-22 17:24:51 UTC (rev 211027)
+++ trunk/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm        2017-01-22 18:51:09 UTC (rev 211028)
</span><span class="lines">@@ -41,6 +41,13 @@
</span><span class="cx"> #include &quot;HTMLCanvasElement.h&quot;
</span><span class="cx"> #include &quot;ImageBuffer.h&quot;
</span><span class="cx"> #include &quot;Logging.h&quot;
</span><ins>+#include &quot;WebGLLayer.h&quot;
+#include &quot;WebGLObject.h&quot;
+#include &quot;WebGLRenderingContextBase.h&quot;
+#include &lt;sys/sysctl.h&gt;
+#include &lt;sysexits.h&gt;
+#include &lt;wtf/text/CString.h&gt;
+
</ins><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx"> #import &quot;OpenGLESSPI.h&quot;
</span><span class="cx"> #import &lt;OpenGLES/ES2/glext.h&gt;
</span><span class="lines">@@ -48,14 +55,10 @@
</span><span class="cx"> #import &lt;OpenGLES/EAGLDrawable.h&gt;
</span><span class="cx"> #import &lt;QuartzCore/QuartzCore.h&gt;
</span><span class="cx"> #else
</span><ins>+#include &lt;IOKit/IOKitLib.h&gt;
</ins><span class="cx"> #include &lt;OpenGL/CGLRenderers.h&gt;
</span><span class="cx"> #include &lt;OpenGL/gl.h&gt;
</span><span class="cx"> #endif
</span><del>-#include &quot;WebGLLayer.h&quot;
-#include &quot;WebGLObject.h&quot;
-#include &quot;WebGLRenderingContextBase.h&quot;
-#include &lt;sysexits.h&gt;
-#include &lt;wtf/text/CString.h&gt;
</del><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="lines">@@ -78,7 +81,80 @@
</span><span class="cx">     ~GraphicsContext3DPrivate() { }
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-#if !PLATFORM(IOS)
</del><ins>+#if PLATFORM(MAC)
+
+enum {
+    kAGCOpen,
+    kAGCClose
+};
+
+static io_connect_t attachToAppleGraphicsControl()
+{
+    mach_port_t masterPort;
+
+    if (IOMasterPort(MACH_PORT_NULL, &amp;masterPort) != KERN_SUCCESS)
+        return MACH_PORT_NULL;
+
+    CFDictionaryRef classToMatch = IOServiceMatching(&quot;AppleGraphicsControl&quot;);
+    if (!classToMatch)
+        return MACH_PORT_NULL;
+
+    kern_return_t kernResult;
+    io_iterator_t iterator;
+    if ((kernResult = IOServiceGetMatchingServices(masterPort, classToMatch, &amp;iterator)) != KERN_SUCCESS)
+        return MACH_PORT_NULL;
+
+    io_service_t serviceObject = IOIteratorNext(iterator);
+    IOObjectRelease(iterator);
+    if (!serviceObject)
+        return MACH_PORT_NULL;
+
+    io_connect_t dataPort;
+    IOObjectRetain(serviceObject);
+    kernResult = IOServiceOpen(serviceObject, mach_task_self(), 0, &amp;dataPort);
+    IOObjectRelease(serviceObject);
+
+    return (kernResult == KERN_SUCCESS) ? dataPort : MACH_PORT_NULL;
+}
+
+static bool hasMuxCapability()
+{
+    io_connect_t dataPort = attachToAppleGraphicsControl();
+
+    if (dataPort == MACH_PORT_NULL)
+        return false;
+
+    bool result;
+    if (IOConnectCallScalarMethod(dataPort, kAGCOpen, nullptr, 0, nullptr, nullptr) == KERN_SUCCESS) {
+        IOConnectCallScalarMethod(dataPort, kAGCClose, nullptr, 0, nullptr, nullptr);
+        result = true;
+    } else
+        result = false;
+
+    IOServiceClose(dataPort);
+
+    if (result) {
+        // This is detecting Mac hardware with an Intel g575 GPU, which
+        // we don't want to make available to muxing.
+        // Based on information from Apple's OpenGL team, such devices
+        // have four or fewer processors.
+        // &lt;rdar://problem/30060378&gt;
+        int names[2] = { CTL_HW, HW_NCPU };
+        int cpuCount;
+        size_t cpuCountLength = sizeof(cpuCount);
+        sysctl(names, 2, &amp;cpuCount, &amp;cpuCountLength, nullptr, 0);
+        result = cpuCount &gt; 4;
+    }
+
+    return result;
+}
+
+static bool hasMuxableGPU()
+{
+    static bool canMux = hasMuxCapability();
+    return canMux;
+}
+
</ins><span class="cx"> static void setPixelFormat(Vector&lt;CGLPixelFormatAttribute&gt;&amp; attribs, int colorBits, int depthBits, bool accelerated, bool supersample, bool closest, bool antialias, bool allowOffline, bool useGLES3)
</span><span class="cx"> {
</span><span class="cx">     attribs.clear();
</span><span class="lines">@@ -92,7 +168,7 @@
</span><span class="cx">     // allowing us to request the integrated graphics on a dual GPU
</span><span class="cx">     // system, and not force the discrete GPU.
</span><span class="cx">     // See https://developer.apple.com/library/mac/technotes/tn2229/_index.html
</span><del>-    if (allowOffline)
</del><ins>+    if (allowOffline &amp;&amp; hasMuxableGPU())
</ins><span class="cx">         attribs.append(kCGLPFAAllowOfflineRenderers);
</span><span class="cx"> 
</span><span class="cx">     if (accelerated)
</span></span></pre>
</div>
</div>

</body>
</html>