<!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>[212633] trunk</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/212633">212633</a></dd>
<dt>Author</dt> <dd>dino@apple.com</dd>
<dt>Date</dt> <dd>2017-02-20 04:28:17 -0800 (Mon, 20 Feb 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Activate/deactivate high performance GPU when requested
https://bugs.webkit.org/show_bug.cgi?id=168559
&lt;rdar://problem/30592266&gt;

Reviewed by Jon Lee.

Source/WebCore:

Respect the high-performance powerPreference for WebGL, by managing an
object that enables the high-performance GPU. If a WebGL context wants
high-performance, and it is visible, then a manager class in GraphicsContext3D
creates and retains the object, causing all the WebGL contexts to move GPUs.
If all the high-performance contexts are not visible, such as in a background tab,
then the manager will release the object, allowing the GPU to power down.

The swapping back from the high-performance GPU happens on a timer, to make
sure we don't churn between GPUs if the user is swapping between a lot of tabs,
or windows.

Unfortunately testing this change properly requires hardware with
multiple GPUs. I plan to write an API test that fakes most of the
system interaction, such as occluding the page. An API test might
also be able to verify if the system has more than one GPU. Otherwise
I'll have to plumb everything through Internals.

* html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::isHighPerformanceContext): Helper to detect if the GraphicsContext3D actually
used high-performance mode.
(WebCore::WebGLRenderingContextBase::create): Add logging if we are
actually overriding a high-performance request.
(WebCore::WebGLRenderingContextBase::WebGLRenderingContextBase): If we are high-performance,
then register for activity state changes.
(WebCore::WebGLRenderingContextBase::addActivityStateChangeObserverIfNecessary):
(WebCore::WebGLRenderingContextBase::removeActivityStateChangeObserver):
(WebCore::WebGLRenderingContextBase::destroyGraphicsContext3D): Call removeActivityStateChangeObserver
as the GC3D is destroyed.
(WebCore::WebGLRenderingContextBase::maybeRestoreContext): If the context was
restored successfully, and came back in high-performance, then we need
to listen for activity state changes as usual.
(WebCore::WebGLRenderingContextBase::activityStateDidChange): If we changed visibility,
tell the GC3D.
* html/canvas/WebGLRenderingContextBase.h: Class inherits ActivityStateChangeObserver.

* page/Settings.in: No longer force low-power everywhere.

* platform/graphics/GraphicsContext3D.cpp:
(WebCore::GraphicsContext3D::setContextVisibility): Empty implementation for non-Mac.
* platform/graphics/GraphicsContext3D.h:
(WebCore::GraphicsContext3D::powerPreferenceUsedForCreation): Tells clients what power preference
was actually used during creation (e.g. a single GPU system will use default, even if
they requested high-performance).

* platform/graphics/mac/GraphicsContext3DMac.mm:
(WebCore::GraphicsContext3DManager::GraphicsContext3DManager): Helper class to
look after all GraphicsContext3Ds.
(WebCore::GraphicsContext3DManager::hasTooManyContexts): We have a limit on the
number of contexts we can keep alive at any one time.
(WebCore::manager): Helper to return the static instance.
(WebCore::displayWasReconfigured): Send a message to all the contexts.
(WebCore::GraphicsContext3DManager::addContext):
(WebCore::GraphicsContext3DManager::removeContext):
(WebCore::GraphicsContext3DManager::addContextRequiringHighPerformance):
(WebCore::GraphicsContext3DManager::removeContextRequiringHighPerformance):
(WebCore::GraphicsContext3DManager::updateHighPerformanceState): Check if the number
of contexts requiring high-performance means we need to enable/disable that GPU.
(WebCore::GraphicsContext3DManager::disableHighPerformanceGPUTimerFired): Releases our
object that keeps the high-performance GPU on.
(WebCore::GraphicsContext3DManager::recycleContextIfNecessary): Get rid of the first (oldest)
context. This code was in GC3D proper, but it made more sense here in the helper.
(WebCore::setPixelFormat): All contexts are created muxable now.
(WebCore::GraphicsContext3D::create): Use the manager.
(WebCore::GraphicsContext3D::GraphicsContext3D): Ditto.
(WebCore::GraphicsContext3D::~GraphicsContext3D): Add logging.
(WebCore::GraphicsContext3D::checkGPUStatusIfNecessary): Better logging.
(WebCore::GraphicsContext3D::updateCGLContext):
(WebCore::GraphicsContext3D::setContextVisibility): This is the responder to the
ActivityStateChanges in the WebGLRenderingContext.
(WebCore::activeContexts): Deleted.
(WebCore::addActiveContext): Deleted.
(WebCore::removeActiveContext): Deleted.

LayoutTests:

We no longer force low-power, so the WebGL canvas creation attributes now
return the value that was passed in.

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

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsfastcanvaswebglcontextcreationattributesexpectedtxt">trunk/LayoutTests/fast/canvas/webgl/context-creation-attributes-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorehtmlcanvasWebGLRenderingContextBasecpp">trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlcanvasWebGLRenderingContextBaseh">trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h</a></li>
<li><a href="#trunkSourceWebCorepageSettingsin">trunk/Source/WebCore/page/Settings.in</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsGraphicsContext3Dcpp">trunk/Source/WebCore/platform/graphics/GraphicsContext3D.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsGraphicsContext3Dh">trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h</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="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (212632 => 212633)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2017-02-20 12:28:00 UTC (rev 212632)
+++ trunk/LayoutTests/ChangeLog        2017-02-20 12:28:17 UTC (rev 212633)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2017-02-19  Dean Jackson  &lt;dino@apple.com&gt;
+
+        Activate/deactivate high performance GPU when requested
+        https://bugs.webkit.org/show_bug.cgi?id=168559
+        &lt;rdar://problem/30592266&gt;
+
+        Reviewed by Jon Lee.
+
+        We no longer force low-power, so the WebGL canvas creation attributes now
+        return the value that was passed in.
+
+        * fast/canvas/webgl/context-creation-attributes-expected.txt:
+
</ins><span class="cx"> 2017-02-20  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed GTK+ gardening. Mark fast/events/message-port-postMessage-recursive.html as timing out.
</span></span></pre></div>
<a id="trunkLayoutTestsfastcanvaswebglcontextcreationattributesexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/canvas/webgl/context-creation-attributes-expected.txt (212632 => 212633)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/canvas/webgl/context-creation-attributes-expected.txt        2017-02-20 12:28:00 UTC (rev 212632)
+++ trunk/LayoutTests/fast/canvas/webgl/context-creation-attributes-expected.txt        2017-02-20 12:28:17 UTC (rev 212633)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> Note that some of the values tested here might not be supported, and thus should return the default values.
</span><span class="cx"> 
</span><del>-{&quot;alpha&quot;:true,&quot;antialias&quot;:true,&quot;depth&quot;:true,&quot;failIfMajorPerformanceCaveat&quot;:false,&quot;powerPreference&quot;:&quot;low-power&quot;,&quot;premultipliedAlpha&quot;:true,&quot;preserveDrawingBuffer&quot;:false,&quot;stencil&quot;:false}
-{&quot;alpha&quot;:true,&quot;antialias&quot;:true,&quot;depth&quot;:true,&quot;failIfMajorPerformanceCaveat&quot;:false,&quot;powerPreference&quot;:&quot;low-power&quot;,&quot;premultipliedAlpha&quot;:true,&quot;preserveDrawingBuffer&quot;:false,&quot;stencil&quot;:true}
-{&quot;alpha&quot;:true,&quot;antialias&quot;:true,&quot;depth&quot;:true,&quot;failIfMajorPerformanceCaveat&quot;:false,&quot;powerPreference&quot;:&quot;low-power&quot;,&quot;premultipliedAlpha&quot;:true,&quot;preserveDrawingBuffer&quot;:false,&quot;stencil&quot;:false}
-{&quot;alpha&quot;:true,&quot;antialias&quot;:true,&quot;depth&quot;:true,&quot;failIfMajorPerformanceCaveat&quot;:true,&quot;powerPreference&quot;:&quot;low-power&quot;,&quot;premultipliedAlpha&quot;:true,&quot;preserveDrawingBuffer&quot;:false,&quot;stencil&quot;:false}
</del><ins>+{&quot;alpha&quot;:true,&quot;antialias&quot;:true,&quot;depth&quot;:true,&quot;failIfMajorPerformanceCaveat&quot;:false,&quot;powerPreference&quot;:&quot;default&quot;,&quot;premultipliedAlpha&quot;:true,&quot;preserveDrawingBuffer&quot;:false,&quot;stencil&quot;:false}
+{&quot;alpha&quot;:true,&quot;antialias&quot;:true,&quot;depth&quot;:true,&quot;failIfMajorPerformanceCaveat&quot;:false,&quot;powerPreference&quot;:&quot;default&quot;,&quot;premultipliedAlpha&quot;:true,&quot;preserveDrawingBuffer&quot;:false,&quot;stencil&quot;:true}
+{&quot;alpha&quot;:true,&quot;antialias&quot;:true,&quot;depth&quot;:true,&quot;failIfMajorPerformanceCaveat&quot;:false,&quot;powerPreference&quot;:&quot;default&quot;,&quot;premultipliedAlpha&quot;:true,&quot;preserveDrawingBuffer&quot;:false,&quot;stencil&quot;:false}
+{&quot;alpha&quot;:true,&quot;antialias&quot;:true,&quot;depth&quot;:true,&quot;failIfMajorPerformanceCaveat&quot;:true,&quot;powerPreference&quot;:&quot;default&quot;,&quot;premultipliedAlpha&quot;:true,&quot;preserveDrawingBuffer&quot;:false,&quot;stencil&quot;:false}
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (212632 => 212633)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2017-02-20 12:28:00 UTC (rev 212632)
+++ trunk/Source/WebCore/ChangeLog        2017-02-20 12:28:17 UTC (rev 212633)
</span><span class="lines">@@ -1,3 +1,84 @@
</span><ins>+2017-02-19  Dean Jackson  &lt;dino@apple.com&gt;
+
+        Activate/deactivate high performance GPU when requested
+        https://bugs.webkit.org/show_bug.cgi?id=168559
+        &lt;rdar://problem/30592266&gt;
+
+        Reviewed by Jon Lee.
+
+        Respect the high-performance powerPreference for WebGL, by managing an
+        object that enables the high-performance GPU. If a WebGL context wants
+        high-performance, and it is visible, then a manager class in GraphicsContext3D
+        creates and retains the object, causing all the WebGL contexts to move GPUs.
+        If all the high-performance contexts are not visible, such as in a background tab,
+        then the manager will release the object, allowing the GPU to power down.
+
+        The swapping back from the high-performance GPU happens on a timer, to make
+        sure we don't churn between GPUs if the user is swapping between a lot of tabs,
+        or windows.
+
+        Unfortunately testing this change properly requires hardware with
+        multiple GPUs. I plan to write an API test that fakes most of the
+        system interaction, such as occluding the page. An API test might
+        also be able to verify if the system has more than one GPU. Otherwise
+        I'll have to plumb everything through Internals.
+
+        * html/canvas/WebGLRenderingContextBase.cpp:
+        (WebCore::isHighPerformanceContext): Helper to detect if the GraphicsContext3D actually
+        used high-performance mode.
+        (WebCore::WebGLRenderingContextBase::create): Add logging if we are
+        actually overriding a high-performance request.
+        (WebCore::WebGLRenderingContextBase::WebGLRenderingContextBase): If we are high-performance,
+        then register for activity state changes.
+        (WebCore::WebGLRenderingContextBase::addActivityStateChangeObserverIfNecessary):
+        (WebCore::WebGLRenderingContextBase::removeActivityStateChangeObserver):
+        (WebCore::WebGLRenderingContextBase::destroyGraphicsContext3D): Call removeActivityStateChangeObserver
+        as the GC3D is destroyed.
+        (WebCore::WebGLRenderingContextBase::maybeRestoreContext): If the context was
+        restored successfully, and came back in high-performance, then we need
+        to listen for activity state changes as usual.
+        (WebCore::WebGLRenderingContextBase::activityStateDidChange): If we changed visibility,
+        tell the GC3D.
+        * html/canvas/WebGLRenderingContextBase.h: Class inherits ActivityStateChangeObserver.
+
+        * page/Settings.in: No longer force low-power everywhere.
+
+        * platform/graphics/GraphicsContext3D.cpp:
+        (WebCore::GraphicsContext3D::setContextVisibility): Empty implementation for non-Mac.
+        * platform/graphics/GraphicsContext3D.h:
+        (WebCore::GraphicsContext3D::powerPreferenceUsedForCreation): Tells clients what power preference
+        was actually used during creation (e.g. a single GPU system will use default, even if
+        they requested high-performance).
+
+        * platform/graphics/mac/GraphicsContext3DMac.mm:
+        (WebCore::GraphicsContext3DManager::GraphicsContext3DManager): Helper class to
+        look after all GraphicsContext3Ds.
+        (WebCore::GraphicsContext3DManager::hasTooManyContexts): We have a limit on the
+        number of contexts we can keep alive at any one time.
+        (WebCore::manager): Helper to return the static instance.
+        (WebCore::displayWasReconfigured): Send a message to all the contexts.
+        (WebCore::GraphicsContext3DManager::addContext):
+        (WebCore::GraphicsContext3DManager::removeContext):
+        (WebCore::GraphicsContext3DManager::addContextRequiringHighPerformance):
+        (WebCore::GraphicsContext3DManager::removeContextRequiringHighPerformance):
+        (WebCore::GraphicsContext3DManager::updateHighPerformanceState): Check if the number
+        of contexts requiring high-performance means we need to enable/disable that GPU.
+        (WebCore::GraphicsContext3DManager::disableHighPerformanceGPUTimerFired): Releases our
+        object that keeps the high-performance GPU on.
+        (WebCore::GraphicsContext3DManager::recycleContextIfNecessary): Get rid of the first (oldest)
+        context. This code was in GC3D proper, but it made more sense here in the helper.
+        (WebCore::setPixelFormat): All contexts are created muxable now.
+        (WebCore::GraphicsContext3D::create): Use the manager.
+        (WebCore::GraphicsContext3D::GraphicsContext3D): Ditto.
+        (WebCore::GraphicsContext3D::~GraphicsContext3D): Add logging.
+        (WebCore::GraphicsContext3D::checkGPUStatusIfNecessary): Better logging.
+        (WebCore::GraphicsContext3D::updateCGLContext):
+        (WebCore::GraphicsContext3D::setContextVisibility): This is the responder to the
+        ActivityStateChanges in the WebGLRenderingContext.
+        (WebCore::activeContexts): Deleted.
+        (WebCore::addActiveContext): Deleted.
+        (WebCore::removeActiveContext): Deleted.
+
</ins><span class="cx"> 2017-02-20  Manuel Rego Casasnovas  &lt;rego@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [css-grid] Remove compilation flag ENABLE_CSS_GRID_LAYOUT
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGLRenderingContextBasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp (212632 => 212633)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp        2017-02-20 12:28:00 UTC (rev 212632)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp        2017-02-20 12:28:17 UTC (rev 212633)
</span><span class="lines">@@ -351,6 +351,11 @@
</span><span class="cx">     WebGLRenderingContextBase* m_context;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+static bool isHighPerformanceContext(const RefPtr&lt;GraphicsContext3D&gt;&amp; context)
+{
+    return context-&gt;powerPreferenceUsedForCreation() == WebGLPowerPreference::HighPerformance;
+}
+
</ins><span class="cx"> std::unique_ptr&lt;WebGLRenderingContextBase&gt; WebGLRenderingContextBase::create(HTMLCanvasElement&amp; canvas, WebGLContextAttributes&amp; attributes, const String&amp; type)
</span><span class="cx"> {
</span><span class="cx"> #if ENABLE(WEBGL2)
</span><span class="lines">@@ -398,8 +403,11 @@
</span><span class="cx">         attributes.forceSoftwareRenderer = true;
</span><span class="cx"> 
</span><span class="cx">     attributes.initialPowerPreference = attributes.powerPreference;
</span><del>-    if (frame-&gt;settings().forceWebGLUsesLowPower())
</del><ins>+    if (frame-&gt;settings().forceWebGLUsesLowPower()) {
+        if (attributes.powerPreference == GraphicsContext3DPowerPreference::HighPerformance)
+            LOG(WebGL, &quot;Overriding powerPreference from high-performance to low-power.&quot;);
</ins><span class="cx">         attributes.powerPreference = GraphicsContext3DPowerPreference::LowPower;
</span><ins>+    }
</ins><span class="cx"> 
</span><span class="cx">     if (page)
</span><span class="cx">         attributes.devicePixelRatio = page-&gt;deviceScaleFactor();
</span><span class="lines">@@ -487,6 +495,8 @@
</span><span class="cx">     initializeNewContext();
</span><span class="cx">     registerWithWebGLStateTracker();
</span><span class="cx">     m_checkForContextLossHandlingTimer.startOneShot(checkContextLossHandlingDelay);
</span><ins>+
+    addActivityStateChangeObserverIfNecessary();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // We check for context loss handling after a few seconds to give the JS a chance to register the event listeners
</span><span class="lines">@@ -615,6 +625,31 @@
</span><span class="cx">         m_compressedTextureFormats.append(format);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebGLRenderingContextBase::addActivityStateChangeObserverIfNecessary()
+{
+    // We are only interested in visibility changes for contexts
+    // that are using the high-performance GPU.
+    if (!isHighPerformanceContext(m_context))
+        return;
+
+    auto* page = canvas().document().page();
+    if (!page)
+        return;
+
+    page-&gt;addActivityStateChangeObserver(*this);
+
+    // We won't get a state change right away, so
+    // make sure the context knows if it visible or not.
+    if (m_context)
+        m_context-&gt;setContextVisibility(page-&gt;isVisible());
+}
+
+void WebGLRenderingContextBase::removeActivityStateChangeObserver()
+{
+    if (auto* page = canvas().document().page())
+        page-&gt;removeActivityStateChangeObserver(*this);
+}
+
</ins><span class="cx"> WebGLRenderingContextBase::~WebGLRenderingContextBase()
</span><span class="cx"> {
</span><span class="cx">     // Remove all references to WebGLObjects so if they are the last reference
</span><span class="lines">@@ -647,6 +682,8 @@
</span><span class="cx">     if (m_isPendingPolicyResolution)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    removeActivityStateChangeObserver();
+
</ins><span class="cx">     if (m_context) {
</span><span class="cx">         m_context-&gt;setContextLostCallback(nullptr);
</span><span class="cx">         m_context-&gt;setErrorMessageCallback(nullptr);
</span><span class="lines">@@ -5586,6 +5623,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     m_context = context;
</span><ins>+    addActivityStateChangeObserverIfNecessary();
</ins><span class="cx">     m_contextLost = false;
</span><span class="cx">     setupFlags();
</span><span class="cx">     initializeNewContext();
</span><span class="lines">@@ -5838,6 +5876,16 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebGLRenderingContextBase::activityStateDidChange(ActivityState::Flags oldActivityState, ActivityState::Flags newActivityState)
+{
+    if (!m_context)
+        return;
+
+    ActivityState::Flags changed = oldActivityState ^ newActivityState;
+    if (changed &amp; ActivityState::IsVisible)
+        m_context-&gt;setContextVisibility(newActivityState &amp; ActivityState::IsVisible);
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(WEBGL)
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGLRenderingContextBaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h (212632 => 212633)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h        2017-02-20 12:28:00 UTC (rev 212632)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h        2017-02-20 12:28:17 UTC (rev 212633)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> #if ENABLE(WEBGL)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;ActiveDOMObject.h&quot;
</span><ins>+#include &quot;ActivityStateChangeObserver.h&quot;
</ins><span class="cx"> #include &quot;CanvasRenderingContext.h&quot;
</span><span class="cx"> #include &quot;GraphicsContext3D.h&quot;
</span><span class="cx"> #include &quot;ImageBuffer.h&quot;
</span><span class="lines">@@ -109,7 +110,7 @@
</span><span class="cx">     return (*clippedX != x || *clippedY != y || *clippedWidth != width || *clippedHeight != height);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-class WebGLRenderingContextBase : public CanvasRenderingContext, public ActiveDOMObject {
</del><ins>+class WebGLRenderingContextBase : public CanvasRenderingContext, private ActivityStateChangeObserver, public ActiveDOMObject {
</ins><span class="cx"> public:
</span><span class="cx">     static std::unique_ptr&lt;WebGLRenderingContextBase&gt; create(HTMLCanvasElement&amp;, WebGLContextAttributes&amp;, const String&amp;);
</span><span class="cx">     virtual ~WebGLRenderingContextBase();
</span><span class="lines">@@ -394,6 +395,9 @@
</span><span class="cx">     void destroyGraphicsContext3D();
</span><span class="cx">     void markContextChanged();
</span><span class="cx"> 
</span><ins>+    void addActivityStateChangeObserverIfNecessary();
+    void removeActivityStateChangeObserver();
+
</ins><span class="cx">     // Query whether it is built on top of compliant GLES2 implementation.
</span><span class="cx">     bool isGLES2Compliant() { return m_isGLES2Compliant; }
</span><span class="cx">     // Query if the GL implementation is NPOT strict.
</span><span class="lines">@@ -831,6 +835,8 @@
</span><span class="cx">     void registerWithWebGLStateTracker();
</span><span class="cx">     void checkForContextLossHandling();
</span><span class="cx"> 
</span><ins>+    void activityStateDidChange(ActivityState::Flags oldActivityState, ActivityState::Flags newActivityState) override;
+
</ins><span class="cx">     WebGLStateTracker::Token m_trackerToken;
</span><span class="cx">     Timer m_checkForContextLossHandlingTimer;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCorepageSettingsin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/Settings.in (212632 => 212633)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/Settings.in        2017-02-20 12:28:00 UTC (rev 212632)
+++ trunk/Source/WebCore/page/Settings.in        2017-02-20 12:28:17 UTC (rev 212633)
</span><span class="lines">@@ -108,7 +108,7 @@
</span><span class="cx"> webGLEnabled initial=false
</span><span class="cx"> webGLErrorsToConsoleEnabled initial=true
</span><span class="cx"> forceSoftwareWebGLRendering initial=false
</span><del>-forceWebGLUsesLowPower initial=true
</del><ins>+forceWebGLUsesLowPower initial=false
</ins><span class="cx"> accelerated2dCanvasEnabled initial=false
</span><span class="cx"> loadDeferringEnabled initial=true
</span><span class="cx"> webAudioEnabled initial=false
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsGraphicsContext3Dcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext3D.cpp (212632 => 212633)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/GraphicsContext3D.cpp        2017-02-20 12:28:00 UTC (rev 212632)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext3D.cpp        2017-02-20 12:28:17 UTC (rev 212633)
</span><span class="lines">@@ -655,6 +655,12 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if !PLATFORM(MAC)
+void GraphicsContext3D::setContextVisibility(bool)
+{
+}
+#endif
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(GRAPHICS_CONTEXT_3D)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsGraphicsContext3Dh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h (212632 => 212633)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h        2017-02-20 12:28:00 UTC (rev 212632)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h        2017-02-20 12:28:17 UTC (rev 212633)
</span><span class="lines">@@ -1143,7 +1143,10 @@
</span><span class="cx"> #if PLATFORM(MAC)
</span><span class="cx">     void updateCGLContext();
</span><span class="cx"> #endif
</span><ins>+    void setContextVisibility(bool);
</ins><span class="cx"> 
</span><ins>+    GraphicsContext3DPowerPreference powerPreferenceUsedForCreation() const { return m_powerPreferenceUsedForCreation; }
+
</ins><span class="cx">     // Support for buffer creation and deletion
</span><span class="cx">     Platform3DObject createBuffer();
</span><span class="cx">     Platform3DObject createFramebuffer();
</span><span class="lines">@@ -1377,6 +1380,7 @@
</span><span class="cx">     friend class Extensions3DOpenGLCommon;
</span><span class="cx"> 
</span><span class="cx">     GraphicsContext3DAttributes m_attrs;
</span><ins>+    GraphicsContext3DPowerPreference m_powerPreferenceUsedForCreation { GraphicsContext3DPowerPreference::Default };
</ins><span class="cx">     RenderStyle m_renderStyle;
</span><span class="cx">     Vector&lt;Vector&lt;float&gt;&gt; m_vertexArray;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsmacGraphicsContext3DMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm (212632 => 212633)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm        2017-02-20 12:28:00 UTC (rev 212632)
+++ trunk/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm        2017-02-20 12:28:17 UTC (rev 212633)
</span><span class="lines">@@ -62,67 +62,8 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-static Vector&lt;GraphicsContext3D*&gt;&amp; activeContexts()
-{
-    static NeverDestroyed&lt;Vector&lt;GraphicsContext3D*&gt;&gt; s_activeContexts;
-    return s_activeContexts;
-}
-
</del><span class="cx"> #if PLATFORM(MAC)
</span><del>-static void displayWasReconfigured(CGDirectDisplayID, CGDisplayChangeSummaryFlags flags, void*)
-{
-    if (flags &amp; kCGDisplaySetModeFlag) {
-        for (auto* context : activeContexts())
-            context-&gt;updateCGLContext();
-    }
-}
-#endif
</del><span class="cx"> 
</span><del>-static void addActiveContext(GraphicsContext3D* context)
-{
-    ASSERT(context);
-    if (!context)
-        return;
-
-    Vector&lt;GraphicsContext3D*&gt;&amp; contexts = activeContexts();
-
-#if PLATFORM(MAC)
-    if (!contexts.size())
-        CGDisplayRegisterReconfigurationCallback(displayWasReconfigured, nullptr);
-#endif
-
-    ASSERT(!contexts.contains(context));
-    contexts.append(context);
-}
-
-static void removeActiveContext(GraphicsContext3D* context)
-{
-    Vector&lt;GraphicsContext3D*&gt;&amp; contexts = activeContexts();
-
-    ASSERT(contexts.contains(context));
-    contexts.removeFirst(context);
-
-#if PLATFORM(MAC)
-    if (!contexts.size())
-        CGDisplayRemoveReconfigurationCallback(displayWasReconfigured, nullptr);
-#endif
-}
-
-const int MaxActiveContexts = 16;
-const int GPUStatusCheckThreshold = 5;
-int GraphicsContext3D::GPUCheckCounter = 0;
-
-// FIXME: This class is currently empty on Mac, but will get populated as 
-// the restructuring in https://bugs.webkit.org/show_bug.cgi?id=66903 is done
-class GraphicsContext3DPrivate {
-public:
-    GraphicsContext3DPrivate(GraphicsContext3D*) { }
-    
-    ~GraphicsContext3DPrivate() { }
-};
-
-#if PLATFORM(MAC)
-
</del><span class="cx"> enum {
</span><span class="cx">     kAGCOpen,
</span><span class="cx">     kAGCClose
</span><span class="lines">@@ -185,7 +126,7 @@
</span><span class="cx">         sysctl(names, 2, &amp;cpuCount, &amp;cpuCountLength, nullptr, 0);
</span><span class="cx">         result = cpuCount &gt; 4;
</span><span class="cx">     }
</span><del>-
</del><ins>+    
</ins><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -195,10 +136,195 @@
</span><span class="cx">     return canMux;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void setPixelFormat(Vector&lt;CGLPixelFormatAttribute&gt;&amp; attribs, int colorBits, int depthBits, bool accelerated, bool supersample, bool closest, bool antialias, GraphicsContext3DPowerPreference powerPreference, bool useGLES3)
</del><ins>+#endif
+
+const unsigned MaxContexts = 16;
+
+class GraphicsContext3DManager {
+public:
+    GraphicsContext3DManager()
+        : m_disableHighPerformanceGPUTimer(*this, &amp;GraphicsContext3DManager::disableHighPerformanceGPUTimerFired)
+    {
+    }
+
+    void addContext(GraphicsContext3D*);
+    void removeContext(GraphicsContext3D*);
+
+    void addContextRequiringHighPerformance(GraphicsContext3D*);
+    void removeContextRequiringHighPerformance(GraphicsContext3D*);
+
+    void recycleContextIfNecessary();
+    bool hasTooManyContexts() const { return m_contexts.size() &gt;= MaxContexts; }
+
+    void updateAllContexts();
+
+private:
+    void updateHighPerformanceState();
+    void disableHighPerformanceGPUTimerFired();
+
+    Vector&lt;GraphicsContext3D*&gt; m_contexts;
+    HashSet&lt;GraphicsContext3D*&gt; m_contextsRequiringHighPerformance;
+
+    Timer m_disableHighPerformanceGPUTimer;
+
+#if PLATFORM(MAC)
+    CGLPixelFormatObj m_pixelFormatObj { nullptr };
+#endif
+};
+
+static GraphicsContext3DManager&amp; manager()
</ins><span class="cx"> {
</span><del>-    bool allowOffline = powerPreference != GraphicsContext3DPowerPreference::HighPerformance;
</del><ins>+    static NeverDestroyed&lt;GraphicsContext3DManager&gt; s_manager;
+    return s_manager;
+}
</ins><span class="cx"> 
</span><ins>+#if PLATFORM(MAC)
+static void displayWasReconfigured(CGDirectDisplayID, CGDisplayChangeSummaryFlags flags, void*)
+{
+    if (flags &amp; kCGDisplaySetModeFlag)
+        manager().updateAllContexts();
+}
+#endif
+
+void GraphicsContext3DManager::updateAllContexts()
+{
+#if PLATFORM(MAC)
+    for (auto* context : m_contexts)
+        context-&gt;updateCGLContext();
+#endif
+}
+
+void GraphicsContext3DManager::addContext(GraphicsContext3D* context)
+{
+    ASSERT(context);
+    if (!context)
+        return;
+
+#if PLATFORM(MAC)
+    if (!m_contexts.size())
+        CGDisplayRegisterReconfigurationCallback(displayWasReconfigured, nullptr);
+#endif
+
+    ASSERT(!m_contexts.contains(context));
+    m_contexts.append(context);
+}
+
+void GraphicsContext3DManager::removeContext(GraphicsContext3D* context)
+{
+    ASSERT(m_contexts.contains(context));
+    m_contexts.removeFirst(context);
+    removeContextRequiringHighPerformance(context);
+
+#if PLATFORM(MAC)
+    if (!m_contexts.size())
+        CGDisplayRemoveReconfigurationCallback(displayWasReconfigured, nullptr);
+#endif
+}
+
+void GraphicsContext3DManager::addContextRequiringHighPerformance(GraphicsContext3D* context)
+{
+    ASSERT(context);
+    if (!context)
+        return;
+
+    ASSERT(m_contexts.contains(context));
+    ASSERT(!m_contextsRequiringHighPerformance.contains(context));
+
+    LOG(WebGL, &quot;This context (%p) requires the high-performance GPU.&quot;, context);
+    m_contextsRequiringHighPerformance.add(context);
+
+    updateHighPerformanceState();
+}
+
+void GraphicsContext3DManager::removeContextRequiringHighPerformance(GraphicsContext3D* context)
+{
+    if (!m_contextsRequiringHighPerformance.contains(context))
+        return;
+
+    LOG(WebGL, &quot;This context (%p) no longer requires the high-performance GPU.&quot;, context);
+    m_contextsRequiringHighPerformance.remove(context);
+
+    updateHighPerformanceState();
+}
+
+void GraphicsContext3DManager::updateHighPerformanceState()
+{
+#if PLATFORM(MAC)
+    if (!hasMuxableGPU())
+        return;
+
+    if (m_contextsRequiringHighPerformance.size()) {
+
+        if (m_disableHighPerformanceGPUTimer.isActive()) {
+            LOG(WebGL, &quot;Cancel pending timer for turning off high-performance GPU.&quot;);
+            m_disableHighPerformanceGPUTimer.stop();
+        }
+
+        if (!m_pixelFormatObj) {
+            LOG(WebGL, &quot;Turning on high-performance GPU.&quot;);
+
+            static NeverDestroyed&lt;Vector&lt;CGLPixelFormatAttribute&gt;&gt; pixelFormatAttributes;
+            Vector&lt;CGLPixelFormatAttribute&gt;&amp; attributes = pixelFormatAttributes.get();
+            if (!attributes.size()) {
+                attributes.append(kCGLPFAAccelerated);
+                attributes.append(kCGLPFAColorSize);
+                attributes.append(static_cast&lt;CGLPixelFormatAttribute&gt;(32));
+                attributes.append(static_cast&lt;CGLPixelFormatAttribute&gt;(0));
+            }
+            GLint numPixelFormats = 0;
+            CGLChoosePixelFormat(attributes.data(), &amp;m_pixelFormatObj, &amp;numPixelFormats);
+        }
+
+    } else if (m_pixelFormatObj) {
+        // Don't immediately turn off the high-performance GPU. The user might be
+        // swapping back and forth between tabs or windows, and we don't want to cause
+        // churn if we can avoid it.
+        if (!m_disableHighPerformanceGPUTimer.isActive()) {
+            LOG(WebGL, &quot;Set a timer to turn off high-performance GPU.&quot;);
+            // FIXME: Expose this value as a Setting, which would require this class
+            // to reference a frame, page or document.
+            static const int timeToKeepHighPerformanceGPUAliveInSeconds = 10;
+            m_disableHighPerformanceGPUTimer.startOneShot(timeToKeepHighPerformanceGPUAliveInSeconds);
+        }
+    }
+#endif
+}
+
+void GraphicsContext3DManager::disableHighPerformanceGPUTimerFired()
+{
+#if PLATFORM(MAC)
+    if (!m_contextsRequiringHighPerformance.size() &amp;&amp; m_pixelFormatObj) {
+        LOG(WebGL, &quot;Turning off high-performance GPU.&quot;);
+        CGLReleasePixelFormat(m_pixelFormatObj);
+        m_pixelFormatObj = nullptr;
+    }
+#endif
+}
+
+void GraphicsContext3DManager::recycleContextIfNecessary()
+{
+    if (hasTooManyContexts()) {
+        LOG(WebGL, &quot;Manager recycled context (%p).&quot;, m_contexts.at(0));
+        m_contexts.at(0)-&gt;recycleContext();
+    }
+}
+
+const int GPUStatusCheckThreshold = 5;
+int GraphicsContext3D::GPUCheckCounter = 0;
+
+// FIXME: This class is currently empty on Mac, but will get populated as 
+// the restructuring in https://bugs.webkit.org/show_bug.cgi?id=66903 is done
+class GraphicsContext3DPrivate {
+public:
+    GraphicsContext3DPrivate(GraphicsContext3D*) { }
+    
+    ~GraphicsContext3DPrivate() { }
+};
+
+#if PLATFORM(MAC)
+
+static void setPixelFormat(Vector&lt;CGLPixelFormatAttribute&gt;&amp; attribs, int colorBits, int depthBits, bool accelerated, bool supersample, bool closest, bool antialias, bool useGLES3)
+{
</ins><span class="cx">     attribs.clear();
</span><span class="cx">     
</span><span class="cx">     attribs.append(kCGLPFAColorSize);
</span><span class="lines">@@ -210,8 +336,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 &amp;&amp; hasMuxableGPU())
-        attribs.append(kCGLPFAAllowOfflineRenderers);
</del><ins>+    attribs.append(kCGLPFAAllowOfflineRenderers);
</ins><span class="cx"> 
</span><span class="cx">     if (accelerated)
</span><span class="cx">         attribs.append(kCGLPFAAccelerated);
</span><span class="lines">@@ -251,14 +376,9 @@
</span><span class="cx">     if (renderStyle == RenderDirectlyToHostWindow)
</span><span class="cx">         return nullptr;
</span><span class="cx"> 
</span><del>-    Vector&lt;GraphicsContext3D*&gt;&amp; contexts = activeContexts();
-    
-    if (contexts.size() &gt;= MaxActiveContexts)
-        contexts.at(0)-&gt;recycleContext();
-    
-    // Calling recycleContext() above should have lead to the graphics context being
-    // destroyed and thus removed from the active contexts list.
-    if (contexts.size() &gt;= MaxActiveContexts)
</del><ins>+    // Make space for the incoming context if we're full.
+    manager().recycleContextIfNecessary();
+    if (manager().hasTooManyContexts())
</ins><span class="cx">         return nullptr;
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;GraphicsContext3D&gt; context = adoptRef(new GraphicsContext3D(attrs, hostWindow, renderStyle));
</span><span class="lines">@@ -266,7 +386,7 @@
</span><span class="cx">     if (!context-&gt;m_contextObj)
</span><span class="cx">         return nullptr;
</span><span class="cx"> 
</span><del>-    addActiveContext(context.get());
</del><ins>+    manager().addContext(context.get());
</ins><span class="cx"> 
</span><span class="cx">     return context;
</span><span class="cx"> }
</span><span class="lines">@@ -319,19 +439,21 @@
</span><span class="cx"> 
</span><span class="cx">     bool useMultisampling = m_attrs.antialias;
</span><span class="cx"> 
</span><del>-    setPixelFormat(attribs, 32, 32, !attrs.forceSoftwareRenderer, true, false, useMultisampling, attrs.powerPreference, attrs.useGLES3);
</del><ins>+    m_powerPreferenceUsedForCreation = (hasMuxableGPU() &amp;&amp; attrs.powerPreference == GraphicsContext3DPowerPreference::HighPerformance) ? GraphicsContext3DPowerPreference::HighPerformance : GraphicsContext3DPowerPreference::Default;
+
+    setPixelFormat(attribs, 32, 32, !attrs.forceSoftwareRenderer, true, false, useMultisampling, attrs.useGLES3);
</ins><span class="cx">     CGLChoosePixelFormat(attribs.data(), &amp;pixelFormatObj, &amp;numPixelFormats);
</span><span class="cx"> 
</span><span class="cx">     if (!numPixelFormats) {
</span><del>-        setPixelFormat(attribs, 32, 32, !attrs.forceSoftwareRenderer, false, false, useMultisampling, attrs.powerPreference, attrs.useGLES3);
</del><ins>+        setPixelFormat(attribs, 32, 32, !attrs.forceSoftwareRenderer, false, false, useMultisampling, attrs.useGLES3);
</ins><span class="cx">         CGLChoosePixelFormat(attribs.data(), &amp;pixelFormatObj, &amp;numPixelFormats);
</span><span class="cx"> 
</span><span class="cx">         if (!numPixelFormats) {
</span><del>-            setPixelFormat(attribs, 32, 16, !attrs.forceSoftwareRenderer, false, false, useMultisampling, attrs.powerPreference, attrs.useGLES3);
</del><ins>+            setPixelFormat(attribs, 32, 16, !attrs.forceSoftwareRenderer, false, false, useMultisampling, attrs.useGLES3);
</ins><span class="cx">             CGLChoosePixelFormat(attribs.data(), &amp;pixelFormatObj, &amp;numPixelFormats);
</span><span class="cx"> 
</span><span class="cx">             if (!attrs.forceSoftwareRenderer &amp;&amp; !numPixelFormats) {
</span><del>-                setPixelFormat(attribs, 32, 16, false, false, true, false, GraphicsContext3DPowerPreference::Default, attrs.useGLES3);
</del><ins>+                setPixelFormat(attribs, 32, 16, false, false, true, false, attrs.useGLES3);
</ins><span class="cx">                 CGLChoosePixelFormat(attribs.data(), &amp;pixelFormatObj, &amp;numPixelFormats);
</span><span class="cx">                 useMultisampling = false;
</span><span class="cx">             }
</span><span class="lines">@@ -445,10 +567,14 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     ::glClearColor(0, 0, 0, 0);
</span><ins>+
+    LOG(WebGL, &quot;Created a GraphicsContext3D (%p).&quot;, this);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> GraphicsContext3D::~GraphicsContext3D()
</span><span class="cx"> {
</span><ins>+    manager().removeContext(this);
+
</ins><span class="cx">     if (m_contextObj) {
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">         makeContextCurrent();
</span><span class="lines">@@ -479,7 +605,7 @@
</span><span class="cx">         [m_webGLLayer setContext:nullptr];
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    removeActiveContext(this);
</del><ins>+    LOG(WebGL, &quot;Destroyed a GraphicsContext3D (%p).&quot;, this);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="lines">@@ -526,11 +652,11 @@
</span><span class="cx"> #if PLATFORM(MAC)
</span><span class="cx">     CGLGetParameter(platformGraphicsContext3D(), kCGLCPGPURestartStatus, &amp;restartStatus);
</span><span class="cx">     if (restartStatus == kCGLCPGPURestartStatusBlacklisted) {
</span><del>-        LOG(WebGL, &quot;The GPU has blacklisted us. Terminating.&quot;);
</del><ins>+        LOG(WebGL, &quot;The GPU has blacklisted us (%p). Terminating.&quot;, this);
</ins><span class="cx">         exit(EX_OSERR);
</span><span class="cx">     }
</span><span class="cx">     if (restartStatus == kCGLCPGPURestartStatusCaused) {
</span><del>-        LOG(WebGL, &quot;The GPU has reset us. Lose the context.&quot;);
</del><ins>+        LOG(WebGL, &quot;The GPU has reset us (%p). Lose the context.&quot;, this);
</ins><span class="cx">         forceContextLost();
</span><span class="cx">         CGLSetCurrentContext(0);
</span><span class="cx">     }
</span><span class="lines">@@ -538,7 +664,7 @@
</span><span class="cx">     EAGLContext* currentContext = static_cast&lt;EAGLContext*&gt;(PlatformGraphicsContext3D());
</span><span class="cx">     [currentContext getParameter:kEAGLCPGPURestartStatus to:&amp;restartStatus];
</span><span class="cx">     if (restartStatus == kEAGLCPGPURestartStatusCaused || restartStatus == kEAGLCPGPURestartStatusBlacklisted) {
</span><del>-        LOG(WebGL, &quot;The GPU has either reset or blacklisted us. Lose the context.&quot;);
</del><ins>+        LOG(WebGL, &quot;The GPU has either reset or blacklisted us (%p). Lose the context.&quot;, this);
</ins><span class="cx">         forceContextLost();
</span><span class="cx">         [EAGLContext setCurrentContext:0];
</span><span class="cx">     }
</span><span class="lines">@@ -564,11 +690,21 @@
</span><span class="cx">     if (!m_contextObj)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    LOG(WebGL, &quot;Detected a mux switch or display reconfiguration. Update the CGLContext.&quot;);
</del><ins>+    LOG(WebGL, &quot;Detected a mux switch or display reconfiguration. Call CGLUpdateContext. (%p)&quot;, this);
</ins><span class="cx"> 
</span><span class="cx">     makeContextCurrent();
</span><span class="cx">     CGLUpdateContext(m_contextObj);
</span><span class="cx"> }
</span><ins>+
+void GraphicsContext3D::setContextVisibility(bool isVisible)
+{
+    if (m_powerPreferenceUsedForCreation == GraphicsContext3DPowerPreference::HighPerformance) {
+        if (isVisible)
+            manager().addContextRequiringHighPerformance(this);
+        else
+            manager().removeContextRequiringHighPerformance(this);
+    }
+}
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> bool GraphicsContext3D::isGLES2Compliant() const
</span></span></pre>
</div>
</div>

</body>
</html>