Enable GPU switching with ANGLE
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 27 Nov 2019 18:59:39 +0000 (18:59 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 27 Nov 2019 18:59:39 +0000 (18:59 +0000)
https://bugs.webkit.org/show_bug.cgi?id=203916

This enables the same GPU switching code that we use with OpenGL on ANGLE
contexts. ANGLE contexts can now be switched to the high power GPU.

Patch by James Darpinian <jdarpinian@chromium.org> on 2019-11-27
Reviewed by Dean Jackson.

* platform/graphics/GraphicsContext3D.h:
* platform/graphics/GraphicsContext3DManager.cpp:
(WebCore::GraphicsContext3DManager::updateAllContexts):
* platform/graphics/cocoa/GraphicsContext3DCocoa.mm:
(WebCore::setGPUByRegistryID):
(WebCore::GraphicsContext3D::GraphicsContext3D):
(WebCore::GraphicsContext3D::updateCGLContext):
(WebCore::GraphicsContext3D::screenDidChange):

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

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/GraphicsContext3D.h
Source/WebCore/platform/graphics/GraphicsContext3DManager.cpp
Source/WebCore/platform/graphics/cocoa/GraphicsContext3DCocoa.mm

index 0b0035d..d471d31 100644 (file)
@@ -1,3 +1,22 @@
+2019-11-27  James Darpinian  <jdarpinian@chromium.org>
+
+        Enable GPU switching with ANGLE
+        https://bugs.webkit.org/show_bug.cgi?id=203916
+
+        This enables the same GPU switching code that we use with OpenGL on ANGLE
+        contexts. ANGLE contexts can now be switched to the high power GPU.
+
+        Reviewed by Dean Jackson.
+
+        * platform/graphics/GraphicsContext3D.h:
+        * platform/graphics/GraphicsContext3DManager.cpp:
+        (WebCore::GraphicsContext3DManager::updateAllContexts):
+        * platform/graphics/cocoa/GraphicsContext3DCocoa.mm:
+        (WebCore::setGPUByRegistryID):
+        (WebCore::GraphicsContext3D::GraphicsContext3D):
+        (WebCore::GraphicsContext3D::updateCGLContext):
+        (WebCore::GraphicsContext3D::screenDidChange):
+
 2019-11-27  Antti Koivisto  <antti@apple.com>
 
         [LFC][Render tree] PerformanceTests/Layout/line-layout-simple.html does not update properly with LFC enabled
index 6e6cb4d..f5317f1 100644 (file)
@@ -1199,15 +1199,12 @@ public:
     void presentRenderbuffer();
 #endif
 
-#if USE(OPENGL)
+#if USE(OPENGL) || USE(ANGLE)
     void allocateIOSurfaceBackingStore(IntSize);
     void updateFramebufferTextureBackingStoreFromLayer();
+#if PLATFORM(MAC)
     void updateCGLContext();
 #endif
-
-#if USE(ANGLE)
-    void allocateIOSurfaceBackingStore(IntSize);
-    void updateFramebufferTextureBackingStoreFromLayer();
 #endif
 #endif // PLATFORM(COCOA)
 
index cfc3776..61861df 100644 (file)
@@ -134,8 +134,7 @@ void GraphicsContext3DManager::displayWasReconfigured(CGDirectDisplayID, CGDispl
 
 void GraphicsContext3DManager::updateAllContexts()
 {
-    // FIXME: determine whether to do anything when using ANGLE.
-#if PLATFORM(MAC) && USE(OPENGL)
+#if PLATFORM(MAC) && (USE(OPENGL) || USE(ANGLE))
     for (const auto& context : m_contexts) {
         context->updateCGLContext();
         context->dispatchContextChangedNotification();
index 0d5837c..63c1cbf 100644 (file)
@@ -57,7 +57,6 @@
 #import <pal/spi/ios/OpenGLESSPI.h>
 #elif USE(OPENGL)
 #import <IOKit/IOKitLib.h>
-#import <OpenGL/CGLRenderers.h>
 #import <OpenGL/gl.h>
 #elif USE(ANGLE)
 #define EGL_EGL_PROTOTYPES 0
@@ -84,6 +83,9 @@ typedef void* GLeglContext;
 
 #if PLATFORM(MAC)
 #import "ScreenProperties.h"
+#if USE(OPENGL) || USE(ANGLE)
+#import <OpenGL/CGLRenderers.h>
+#endif
 #endif
 
 namespace WebCore {
@@ -131,9 +133,9 @@ Ref<GraphicsContext3D> GraphicsContext3D::createShared(GraphicsContext3D& shared
     return context;
 }
 
-#if PLATFORM(MAC) && USE(OPENGL) // FIXME: This probably should be just USE(OPENGL) - see <rdar://53062794>.
+#if PLATFORM(MAC) && (USE(OPENGL) || USE(ANGLE)) // FIXME: This probably should be just (USE(OPENGL) || USE(ANGLE)) - see <rdar://53062794>.
 
-static void setGPUByRegistryID(PlatformGraphicsContext3D contextObj, CGLPixelFormatObj pixelFormatObj, IORegistryGPUID preferredGPUID)
+static void setGPUByRegistryID(CGLContextObj contextObj, CGLPixelFormatObj pixelFormatObj, IORegistryGPUID preferredGPUID)
 {
     // When the WebProcess does not have access to the WindowServer, there is no way for OpenGL to tell which GPU is connected to a display.
     // On 10.13+, find the virtual screen that corresponds to the preferred GPU by its registryID.
@@ -289,8 +291,6 @@ GraphicsContext3D::GraphicsContext3D(GraphicsContext3DAttributes attrs, HostWind
 
 #elif USE(ANGLE)
 
-    UNUSED_PARAM(hostWindow);
-
     m_displayObj = EGL_GetDisplay(EGL_DEFAULT_DISPLAY);
     if (m_displayObj == EGL_NO_DISPLAY)
         return;
@@ -372,6 +372,17 @@ GraphicsContext3D::GraphicsContext3D(GraphicsContext3DAttributes attrs, HostWind
 
         extensions.ensureEnabled(requiredExtensions[i]);
     }
+
+    EGLDeviceEXT device = nullptr;
+    EGL_QueryDisplayAttribEXT(m_displayObj, EGL_DEVICE_EXT, reinterpret_cast<EGLAttrib*>(&device));
+    CGLContextObj cglContext = nullptr;
+    CGLPixelFormatObj pixelFormat = nullptr;
+    EGL_QueryDeviceAttribEXT(device, EGL_CGL_CONTEXT_ANGLE, reinterpret_cast<EGLAttrib*>(&cglContext));
+    EGL_QueryDeviceAttribEXT(device, EGL_CGL_PIXEL_FORMAT_ANGLE, reinterpret_cast<EGLAttrib*>(&pixelFormat));
+    auto gpuID = (hostWindow && hostWindow->displayID()) ? gpuIDForDisplay(hostWindow->displayID()) : primaryGPUID();
+    setGPUByRegistryID(cglContext, pixelFormat, gpuID);
+#else
+    UNUSED_PARAM(hostWindow);
 #endif // PLATFORM(MAC)
 
 #endif // #elif USE(ANGLE)
@@ -716,6 +727,26 @@ void GraphicsContext3D::setContextVisibility(bool isVisible)
 #endif // USE(OPENGL) || USE(ANGLE)
 
 #if USE(ANGLE)
+
+#if PLATFORM(MAC)
+void GraphicsContext3D::updateCGLContext()
+{
+    if (!m_contextObj)
+        return;
+
+    LOG(WebGL, "Detected a mux switch or display reconfiguration. Call CGLUpdateContext. (%p)", this);
+
+    makeContextCurrent();
+    EGLDeviceEXT device = nullptr;
+    EGL_QueryDisplayAttribEXT(m_displayObj, EGL_DEVICE_EXT, reinterpret_cast<EGLAttrib*>(&device));
+    CGLContextObj cglContext = nullptr;
+    EGL_QueryDeviceAttribEXT(device, EGL_CGL_CONTEXT_ANGLE, reinterpret_cast<EGLAttrib*>(&cglContext));
+
+    CGLUpdateContext(cglContext);
+    m_hasSwitchedToHighPerformanceGPU = true;
+}
+#endif
+
 void GraphicsContext3D::allocateIOSurfaceBackingStore(IntSize size)
 {
 #if HAVE(IOSURFACE)
@@ -784,9 +815,16 @@ void GraphicsContext3D::screenDidChange(PlatformDisplayID displayID)
     if (!m_contextObj)
         return;
 #if USE(ANGLE)
-    UNUSED_PARAM(displayID);
+    if (!m_hasSwitchedToHighPerformanceGPU) {
+        EGLDeviceEXT device = nullptr;
+        EGL_QueryDisplayAttribEXT(m_displayObj, EGL_DEVICE_EXT, reinterpret_cast<EGLAttrib*>(&device));
+        CGLContextObj cglContext = nullptr;
+        CGLPixelFormatObj pixelFormat = nullptr;
+        EGL_QueryDeviceAttribEXT(device, EGL_CGL_CONTEXT_ANGLE, reinterpret_cast<EGLAttrib*>(&cglContext));
+        EGL_QueryDeviceAttribEXT(device, EGL_CGL_PIXEL_FORMAT_ANGLE, reinterpret_cast<EGLAttrib*>(&pixelFormat));
+        setGPUByRegistryID(cglContext, pixelFormat, gpuIDForDisplay(displayID));
+    }
 #else
-    // FIXME: figure out whether to integrate more code into ANGLE to have this effect.
 #if USE(OPENGL)
     if (!m_hasSwitchedToHighPerformanceGPU)
         setGPUByRegistryID(m_contextObj, CGLGetPixelFormat(m_contextObj), gpuIDForDisplay(displayID));