Changeset 271880 in webkit


Ignore:
Timestamp:
Jan 26, 2021 5:43:59 AM (18 months ago)
Author:
commit-queue@webkit.org
Message:

WebGL power preference and discrete/internal gpu selection implemented incorrectly with ANGLE
https://bugs.webkit.org/show_bug.cgi?id=220843

Patch by Kimmo Kinnunen <kkinnunen@apple.com> on 2021-01-26
Reviewed by Dean Jackson.

Source/WebCore:

Use ANGLE extension EGL_ANGLE_power_preference to signal to ANGLE that the underlying
CGL context should be updated as a response to display reconfiguration signal.
This ensures that ANGLE state stays consistent with the actual CGL context behavior, as
we don't change the context behind ANGLE's back.

Remove the feature where the context GPU is selected based on the display the window is
on. This cannot work with the logic of "powerPreference = "high-performance" goes to
discrete GPU". Also, this cannot work with ANGLE at all, since all contexts are backed
by a single platform context. Thus all contexts will use the same underlying GPU.

No new tests due to the test runner missing features. The bug blockers track the testing.

  • PlatformMac.cmake:
  • SourcesCocoa.txt:
  • WebCore.xcodeproj/project.pbxproj:
  • html/canvas/WebGLRenderingContextBase.cpp:

(WebCore::isHighPerformanceContext):

  • page/Chrome.cpp:

(WebCore::Chrome::windowScreenDidChange):

  • platform/graphics/GraphicsContextGL.h:
  • platform/graphics/RemoteGraphicsContextGLProxyBase.cpp:
  • platform/graphics/RemoteGraphicsContextGLProxyBase.h:
  • platform/graphics/cocoa/GraphicsContextGLOpenGLCocoa.mm:

(WebCore::GraphicsContextGLOpenGL::create):
(WebCore::GraphicsContextGLOpenGL::createShared):
(WebCore::GraphicsContextGLOpenGL::GraphicsContextGLOpenGL):
(WebCore::GraphicsContextGLOpenGL::setContextVisibility):
(WebCore::GraphicsContextGLOpenGL::displayWasReconfigured):
(WebCore::GraphicsContextGLOpenGL::simulateContextChanged):

  • platform/graphics/mac/GraphicsChecksMac.cpp: Added.

(WebCore::attachToAppleGraphicsControl):
(WebCore::hasMuxCapability):
(WebCore::hasLowAndHighPowerGPUs):

  • platform/graphics/mac/GraphicsChecksMac.h: Copied from Source/WebKit/WebProcess/WebCoreSupport/mac/WebSwitchingGPUClient.h.
  • platform/graphics/mac/ScopedHighPerformanceGPURequest.h: Copied from Source/WebCore/platform/graphics/mac/SwitchingGPUClient.h.

(WebCore::ScopedHighPerformanceGPURequest::ScopedHighPerformanceGPURequest):
(WebCore::ScopedHighPerformanceGPURequest::~ScopedHighPerformanceGPURequest):
(WebCore::ScopedHighPerformanceGPURequest::operator=):
(WebCore::ScopedHighPerformanceGPURequest::acquire):

  • platform/graphics/mac/SwitchingGPUClient.h:
  • platform/graphics/opengl/GraphicsContextGLOpenGL.h:
  • platform/graphics/opengl/GraphicsContextGLOpenGLManager.cpp:

(WebCore::GraphicsContextGLOpenGLManager::displayWasReconfigured):
(WebCore::GraphicsContextGLOpenGLManager::addContext):
(WebCore::GraphicsContextGLOpenGLManager::removeContext):

  • platform/graphics/opengl/GraphicsContextGLOpenGLManager.h:
  • testing/Internals.cpp:

Source/WebKit:

Move the high-performance GPU shutdown timer from individual web processes to the main class
in the ui process. This simplifies the implementation and reduces the number of timers.

  • UIProcess/mac/HighPerformanceGPUManager.h:
  • UIProcess/mac/HighPerformanceGPUManager.mm:

(WebKit::HighPerformanceGPUManager::HighPerformanceGPUManager):
(WebKit::HighPerformanceGPUManager::removeProcessRequiringHighPerformance):
(WebKit::HighPerformanceGPUManager::updateState):

  • WebProcess/WebCoreSupport/mac/WebSwitchingGPUClient.cpp:

(WebKit::WebSwitchingGPUClient::requestHighPerformanceGPU):
(WebKit::WebSwitchingGPUClient::releaseHighPerformanceGPU):

  • WebProcess/WebCoreSupport/mac/WebSwitchingGPUClient.h:
Location:
trunk/Source
Files:
1 added
20 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r271878 r271880  
     12021-01-26  Kimmo Kinnunen  <kkinnunen@apple.com>
     2
     3        WebGL power preference and discrete/internal gpu selection implemented incorrectly with ANGLE
     4        https://bugs.webkit.org/show_bug.cgi?id=220843
     5
     6        Reviewed by Dean Jackson.
     7
     8        Use ANGLE extension EGL_ANGLE_power_preference to signal to ANGLE that the underlying
     9        CGL context should be updated as a response to display reconfiguration signal.
     10        This ensures that ANGLE state stays consistent with the actual CGL context behavior, as
     11        we don't change the context behind ANGLE's back.
     12
     13        Remove the feature where the context GPU is selected based on the display the window is
     14        on. This cannot work with the logic of "powerPreference = "high-performance" goes to
     15        discrete GPU". Also, this cannot work with ANGLE at all, since all contexts are backed
     16        by a single platform context. Thus all contexts will use the same underlying GPU.
     17
     18        No new tests due to the test runner missing features. The bug blockers track the testing.
     19
     20        * PlatformMac.cmake:
     21        * SourcesCocoa.txt:
     22        * WebCore.xcodeproj/project.pbxproj:
     23        * html/canvas/WebGLRenderingContextBase.cpp:
     24        (WebCore::isHighPerformanceContext):
     25        * page/Chrome.cpp:
     26        (WebCore::Chrome::windowScreenDidChange):
     27        * platform/graphics/GraphicsContextGL.h:
     28        * platform/graphics/RemoteGraphicsContextGLProxyBase.cpp:
     29        * platform/graphics/RemoteGraphicsContextGLProxyBase.h:
     30        * platform/graphics/cocoa/GraphicsContextGLOpenGLCocoa.mm:
     31        (WebCore::GraphicsContextGLOpenGL::create):
     32        (WebCore::GraphicsContextGLOpenGL::createShared):
     33        (WebCore::GraphicsContextGLOpenGL::GraphicsContextGLOpenGL):
     34        (WebCore::GraphicsContextGLOpenGL::setContextVisibility):
     35        (WebCore::GraphicsContextGLOpenGL::displayWasReconfigured):
     36        (WebCore::GraphicsContextGLOpenGL::simulateContextChanged):
     37        * platform/graphics/mac/GraphicsChecksMac.cpp: Added.
     38        (WebCore::attachToAppleGraphicsControl):
     39        (WebCore::hasMuxCapability):
     40        (WebCore::hasLowAndHighPowerGPUs):
     41        * platform/graphics/mac/GraphicsChecksMac.h: Copied from Source/WebKit/WebProcess/WebCoreSupport/mac/WebSwitchingGPUClient.h.
     42        * platform/graphics/mac/ScopedHighPerformanceGPURequest.h: Copied from Source/WebCore/platform/graphics/mac/SwitchingGPUClient.h.
     43        (WebCore::ScopedHighPerformanceGPURequest::ScopedHighPerformanceGPURequest):
     44        (WebCore::ScopedHighPerformanceGPURequest::~ScopedHighPerformanceGPURequest):
     45        (WebCore::ScopedHighPerformanceGPURequest::operator=):
     46        (WebCore::ScopedHighPerformanceGPURequest::acquire):
     47        * platform/graphics/mac/SwitchingGPUClient.h:
     48        * platform/graphics/opengl/GraphicsContextGLOpenGL.h:
     49        * platform/graphics/opengl/GraphicsContextGLOpenGLManager.cpp:
     50        (WebCore::GraphicsContextGLOpenGLManager::displayWasReconfigured):
     51        (WebCore::GraphicsContextGLOpenGLManager::addContext):
     52        (WebCore::GraphicsContextGLOpenGLManager::removeContext):
     53        * platform/graphics/opengl/GraphicsContextGLOpenGLManager.h:
     54        * testing/Internals.cpp:
     55
    1562021-01-25  Ryosuke Niwa  <rniwa@webkit.org>
    257
  • trunk/Source/WebCore/PlatformMac.cmake

    r271089 r271880  
    341341    platform/graphics/mac/FloatSizeMac.mm
    342342    platform/graphics/mac/FontCustomPlatformData.cpp
     343    platform/graphics/mac/GraphicsChecksMac.cpp
    343344    platform/graphics/mac/IconMac.mm
    344345    platform/graphics/mac/ImageMac.mm
  • trunk/Source/WebCore/SourcesCocoa.txt

    r271089 r271880  
    419419platform/graphics/mac/FloatSizeMac.mm
    420420platform/graphics/mac/FontCustomPlatformData.cpp
     421platform/graphics/mac/GraphicsChecksMac.cpp
    421422platform/graphics/mac/IconMac.mm
    422423platform/graphics/mac/ImageMac.mm
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r271806 r271880  
    22632263                7BB34A1725345CB200029D08 /* GraphicsContextGLANGLEUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BB34A1625345CB200029D08 /* GraphicsContextGLANGLEUtilities.h */; };
    22642264                7BB34A48253776CA00029D08 /* GraphicsContextGLImageExtractor.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BB34A45253776C600029D08 /* GraphicsContextGLImageExtractor.h */; settings = {ATTRIBUTES = (Private, ); }; };
     2265                7BB680B225BA0D4A002B8738 /* ScopedHighPerformanceGPURequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BB680B025BA0D4A002B8738 /* ScopedHighPerformanceGPURequest.h */; settings = {ATTRIBUTES = (Private, ); }; };
     2266                7BB680B625BA1AE2002B8738 /* ScopedHighPerformanceGPURequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BB680B425BA1AE1002B8738 /* ScopedHighPerformanceGPURequest.h */; };
     2267                7BB680BA25BA1BE4002B8738 /* GraphicsChecksMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BB680B825BA1BE4002B8738 /* GraphicsChecksMac.h */; settings = {ATTRIBUTES = (Private, ); }; };
    22652268                7BE7427381FA906FBB4F0F2C /* JSSVGGraphicsElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 950C4C02BED8936F818E2F99 /* JSSVGGraphicsElement.h */; };
    22662269                7C029C6E2493C8F800268204 /* ColorTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C029C6D2493C8F800268204 /* ColorTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    1030210305                7BB34A45253776C600029D08 /* GraphicsContextGLImageExtractor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GraphicsContextGLImageExtractor.h; sourceTree = "<group>"; };
    1030310306                7BB34A47253776C700029D08 /* GraphicsContextGLImageExtractor.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GraphicsContextGLImageExtractor.cpp; sourceTree = "<group>"; };
     10307                7BB680B025BA0D4A002B8738 /* ScopedHighPerformanceGPURequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScopedHighPerformanceGPURequest.h; sourceTree = "<group>"; };
     10308                7BB680B425BA1AE1002B8738 /* ScopedHighPerformanceGPURequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScopedHighPerformanceGPURequest.h; sourceTree = "<group>"; };
     10309                7BB680B725BA1BE3002B8738 /* GraphicsChecksMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GraphicsChecksMac.cpp; sourceTree = "<group>"; };
     10310                7BB680B825BA1BE4002B8738 /* GraphicsChecksMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GraphicsChecksMac.h; sourceTree = "<group>"; };
    1030410311                7BE7265B25763B8D00E85D98 /* RemoteGraphicsContextGLProxyBase.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = RemoteGraphicsContextGLProxyBase.cpp; sourceTree = "<group>"; };
    1030510312                7C011F3D24FAD360005BEF10 /* Settings.cpp.erb */ = {isa = PBXFileReference; lastKnownFileType = text; path = Settings.cpp.erb; sourceTree = "<group>"; };
     
    2650426511                                B2AFFC750D00A5C10030074D /* FontCustomPlatformData.cpp */,
    2650526512                                B2AFFC760D00A5C10030074D /* FontCustomPlatformData.h */,
     26513                                7BB680B725BA1BE3002B8738 /* GraphicsChecksMac.cpp */,
     26514                                7BB680B825BA1BE4002B8738 /* GraphicsChecksMac.h */,
    2650626515                                B275358D0B053A66002CE64F /* IconMac.mm */,
    2650726516                                B275354E0B053814002CE64F /* ImageMac.mm */,
     
    2650926518                                B27535510B053814002CE64F /* IntSizeMac.mm */,
    2651026519                                2D6E468217D660F500ECF8BB /* PDFDocumentImageMac.mm */,
     26520                                7BB680B425BA1AE1002B8738 /* ScopedHighPerformanceGPURequest.h */,
     26521                                7BB680B025BA0D4A002B8738 /* ScopedHighPerformanceGPURequest.h */,
    2651126522                                163E88F5118A39D200ED9231 /* SimpleFontDataCoreText.cpp */,
    2651226523                                C11A9ED22140578B00CFB20A /* SwitchingGPUClient.cpp */,
     
    3224832259                                B22279640D00BF220071B782 /* GradientAttributes.h in Headers */,
    3224932260                                2D481F04146B5C6B00AA7834 /* GradientImage.h in Headers */,
     32261                                7BB680BA25BA1BE4002B8738 /* GraphicsChecksMac.h in Headers */,
    3225032262                                B2A015A90AF6CD53006BCE0E /* GraphicsContext.h in Headers */,
    3225132263                                934907E4125BBBC8007F23A0 /* GraphicsContextCG.h in Headers */,
     
    3447034482                                5DFE8F570D16477C0076E937 /* ScheduledAction.h in Headers */,
    3447134483                                9BD0BF9312A42BF50072FD43 /* ScopedEventQueue.h in Headers */,
     34484                                7BB680B625BA1AE2002B8738 /* ScopedHighPerformanceGPURequest.h in Headers */,
     34485                                7BB680B225BA0D4A002B8738 /* ScopedHighPerformanceGPURequest.h in Headers */,
    3447234486                                BCEC01BE0C274DAC009F4EC9 /* Screen.h in Headers */,
    3447334487                                C1E1D236203DF15400584665 /* ScreenProperties.h in Headers */,
  • trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp

    r271679 r271880  
    643643static bool isHighPerformanceContext(const RefPtr<GraphicsContextGL>& context)
    644644{
    645     return context->powerPreferenceUsedForCreation() == WebGLPowerPreference::HighPerformance;
     645    return context->contextAttributes().powerPreference == WebGLPowerPreference::HighPerformance;
    646646}
    647647
  • trunk/Source/WebCore/page/Chrome.cpp

    r270587 r271880  
    6868#endif
    6969
    70 #if PLATFORM(MAC) && ENABLE(WEBGL)
    71 #include "GraphicsContextGLOpenGLManager.h"
    72 #endif
    73 
    7470namespace WebCore {
    7571
     
    549545
    550546    m_page.windowScreenDidChange(displayID, nominalFrameInterval);
    551 
    552 #if PLATFORM(MAC) && ENABLE(WEBGL)
    553     GraphicsContextGLOpenGLManager::sharedManager().screenDidChange(displayID, this);
    554 #endif
    555547}
    556548
  • trunk/Source/WebCore/platform/graphics/GraphicsContextGL.h

    r271679 r271880  
    12641264    virtual void setContextVisibility(bool) = 0;
    12651265
    1266     virtual GraphicsContextGLPowerPreference powerPreferenceUsedForCreation() const = 0;
    1267 
    12681266    virtual bool isGLES2Compliant() const = 0;
    12691267
  • trunk/Source/WebCore/platform/graphics/RemoteGraphicsContextGLProxyBase.cpp

    r271065 r271880  
    4848{
    4949    notImplemented();
    50 }
    51 
    52 GraphicsContextGLPowerPreference RemoteGraphicsContextGLProxyBase::powerPreferenceUsedForCreation() const
    53 {
    54     notImplemented();
    55     return { };
    5650}
    5751
  • trunk/Source/WebCore/platform/graphics/RemoteGraphicsContextGLProxyBase.h

    r270964 r271880  
    6262    ExtensionsGL& getExtensions() final;
    6363    void setContextVisibility(bool) final;
    64     GraphicsContextGLPowerPreference powerPreferenceUsedForCreation() const final;
    6564    bool isGLES2Compliant() const final;
    6665    void markContextChanged() final;
  • trunk/Source/WebCore/platform/graphics/cocoa/GraphicsContextGLOpenGLCocoa.mm

    r271609 r271880  
    2121 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    2222 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
     23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2424 */
    2525
     
    3333#import "GraphicsContextGLIOSurfaceSwapChain.h"
    3434#import "GraphicsContextGLOpenGLManager.h"
    35 #import "HostWindow.h"
    3635#import "Logging.h"
    37 #import "OpenGLSoftLinkCocoa.h"
    3836#import "RuntimeApplicationChecks.h"
    3937#import "WebCoreThread.h"
     
    4240#import <wtf/BlockObjCExceptions.h>
    4341#import <wtf/text/CString.h>
    44 
    45 #if PLATFORM(MAC)
    46 #import "ScreenProperties.h"
    47 #import <OpenGL/CGLRenderers.h>
    48 #endif
    4942
    5043#if ENABLE(VIDEO) && USE(AVFOUNDATION)
     
    152145        return nullptr;
    153146
    154     GraphicsContextGLOpenGLManager::sharedManager().addContext(context.get(), hostWindow);
     147    GraphicsContextGLOpenGLManager::sharedManager().addContext(context.get());
    155148
    156149    return context;
     
    159152Ref<GraphicsContextGLOpenGL> GraphicsContextGLOpenGL::createShared(GraphicsContextGLOpenGL& sharedContext)
    160153{
    161     auto hostWindow = GraphicsContextGLOpenGLManager::sharedManager().hostWindowForContext(&sharedContext);
    162     auto context = adoptRef(*new GraphicsContextGLOpenGL(sharedContext.contextAttributes(), hostWindow, &sharedContext, nullptr));
    163 
    164     GraphicsContextGLOpenGLManager::sharedManager().addContext(context.ptr(), hostWindow);
     154
     155    auto context = adoptRef(*new GraphicsContextGLOpenGL(sharedContext.contextAttributes(), nullptr, &sharedContext, nullptr));
     156
     157    GraphicsContextGLOpenGLManager::sharedManager().addContext(context.ptr());
    165158
    166159    return context;
     
    172165}
    173166
    174 #if PLATFORM(MAC) // FIXME: This probably should be just enabled - see <rdar://53062794>.
    175 
    176 static void setGPUByRegistryID(CGLContextObj contextObj, CGLPixelFormatObj pixelFormatObj, IORegistryGPUID preferredGPUID)
    177 {
    178     // 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.
    179     // On 10.13+, find the virtual screen that corresponds to the preferred GPU by its registryID.
    180     // CGLSetVirtualScreen can then be used to tell OpenGL which GPU it should be using.
    181 
    182     if (!contextObj || !preferredGPUID)
    183         return;
    184 
    185     GLint virtualScreenCount = 0;
    186     CGLError error = CGLDescribePixelFormat(pixelFormatObj, 0, kCGLPFAVirtualScreenCount, &virtualScreenCount);
    187     ASSERT(error == kCGLNoError);
    188 
    189     GLint firstAcceleratedScreen = -1;
    190 
    191     for (GLint virtualScreen = 0; virtualScreen < virtualScreenCount; ++virtualScreen) {
    192         GLint displayMask = 0;
    193         error = CGLDescribePixelFormat(pixelFormatObj, virtualScreen, kCGLPFADisplayMask, &displayMask);
    194         ASSERT(error == kCGLNoError);
    195 
    196         auto gpuID = gpuIDForDisplayMask(displayMask);
    197 
    198         if (gpuID == preferredGPUID) {
    199             error = CGLSetVirtualScreen(contextObj, virtualScreen);
    200             ASSERT(error == kCGLNoError);
    201             LOG(WebGL, "Context (%p) set to GPU with ID: (%lld).", contextObj, gpuID);
    202             return;
    203         }
    204 
    205         if (firstAcceleratedScreen < 0) {
    206             GLint isAccelerated = 0;
    207             error = CGLDescribePixelFormat(pixelFormatObj, virtualScreen, kCGLPFAAccelerated, &isAccelerated);
    208             ASSERT(error == kCGLNoError);
    209             if (isAccelerated)
    210                 firstAcceleratedScreen = virtualScreen;
    211         }
    212     }
    213 
    214     // No registryID match found; set to first hardware-accelerated virtual screen.
    215     if (firstAcceleratedScreen >= 0) {
    216         error = CGLSetVirtualScreen(contextObj, firstAcceleratedScreen);
    217         ASSERT(error == kCGLNoError);
    218         LOG(WebGL, "RegistryID (%lld) not matched; Context (%p) set to virtual screen (%d).", preferredGPUID, contextObj, firstAcceleratedScreen);
    219     }
    220 }
    221 
    222 #endif // PLATFORM(MAC)
    223 
    224 GraphicsContextGLOpenGL::GraphicsContextGLOpenGL(GraphicsContextGLAttributes attrs, HostWindow* hostWindow, GraphicsContextGLOpenGL* sharedContext, GraphicsContextGLIOSurfaceSwapChain* swapChain)
     167GraphicsContextGLOpenGL::GraphicsContextGLOpenGL(GraphicsContextGLAttributes attrs, HostWindow*, GraphicsContextGLOpenGL* sharedContext, GraphicsContextGLIOSurfaceSwapChain* swapChain)
    225168    : GraphicsContextGL(attrs, Destination::Offscreen, sharedContext)
    226169{
    227170    m_isForWebGL2 = attrs.webGLVersion == GraphicsContextGLWebGLVersion::WebGL2;
    228 
    229 #if HAVE(APPLE_GRAPHICS_CONTROL)
    230     m_powerPreferenceUsedForCreation = (hasLowAndHighPowerGPUs() && attrs.powerPreference == GraphicsContextGLPowerPreference::HighPerformance) ? GraphicsContextGLPowerPreference::HighPerformance : GraphicsContextGLPowerPreference::Default;
    231 #else
    232     m_powerPreferenceUsedForCreation = GraphicsContextGLPowerPreference::Default;
    233 #endif
    234171
    235172    m_displayObj = InitializeEGLDisplay(attrs);
    236173    if (m_displayObj == EGL_NO_DISPLAY)
    237174        return;
     175
     176    bool supportsPowerPreference = false;
     177#if PLATFORM(MAC)
    238178    const char *displayExtensions = EGL_QueryString(m_displayObj, EGL_EXTENSIONS);
    239     LOG(WebGL, "Extensions: %s", displayExtensions);
     179    m_supportsPowerPreference = strstr(displayExtensions, "EGL_ANGLE_power_preference");
     180    supportsPowerPreference = m_supportsPowerPreference;
     181#endif
     182    if (!supportsPowerPreference && attrs.powerPreference == GraphicsContextGLPowerPreference::HighPerformance) {
     183        attrs.powerPreference = GraphicsContextGLPowerPreference::Default;
     184        setContextAttributes(attrs);
     185    }
    240186
    241187    EGLint configAttributes[] = {
     
    291237    eglContextAttributes.append(EGL_FALSE);
    292238
    293     if (strstr(displayExtensions, "EGL_ANGLE_power_preference")) {
    294         eglContextAttributes.append(EGL_POWER_PREFERENCE_ANGLE);
    295         // EGL_LOW_POWER_ANGLE is the default. Change to
    296         // EGL_HIGH_POWER_ANGLE if desired.
    297         eglContextAttributes.append(EGL_LOW_POWER_ANGLE);
    298     }
    299239    eglContextAttributes.append(EGL_NONE);
    300240
     
    333273        extensions.ensureEnabled(extension);
    334274    }
    335 #if PLATFORM(MAC)
    336     // FIXME: It's unclear if MACCATALYST should take these steps as well, but that
    337     // would require the PlatformScreenMac code to be exposed to Catalyst too.
    338     EGLDeviceEXT device = nullptr;
    339     EGL_QueryDisplayAttribEXT(m_displayObj, EGL_DEVICE_EXT, reinterpret_cast<EGLAttrib*>(&device));
    340     CGLContextObj cglContext = nullptr;
    341     CGLPixelFormatObj pixelFormat = nullptr;
    342     EGL_QueryDeviceAttribEXT(device, EGL_CGL_CONTEXT_ANGLE, reinterpret_cast<EGLAttrib*>(&cglContext));
    343     EGL_QueryDeviceAttribEXT(device, EGL_CGL_PIXEL_FORMAT_ANGLE, reinterpret_cast<EGLAttrib*>(&pixelFormat));
    344     auto gpuID = (hostWindow && hostWindow->displayID()) ? gpuIDForDisplay(hostWindow->displayID()) : primaryGPUID();
    345     setGPUByRegistryID(cglContext, pixelFormat, gpuID);
    346 #else
    347     UNUSED_PARAM(hostWindow);
    348 #endif
    349 
    350275    validateAttributes();
    351276    attrs = contextAttributes(); // They may have changed during validation.
     
    562487void GraphicsContextGLOpenGL::setContextVisibility(bool isVisible)
    563488{
    564     if (m_powerPreferenceUsedForCreation == GraphicsContextGLPowerPreference::HighPerformance) {
    565         if (isVisible)
    566             GraphicsContextGLOpenGLManager::sharedManager().addContextRequiringHighPerformance(this);
    567         else
    568             GraphicsContextGLOpenGLManager::sharedManager().removeContextRequiringHighPerformance(this);
    569     }
    570 }
    571 
    572489#if PLATFORM(MAC)
    573 void GraphicsContextGLOpenGL::updateCGLContext()
    574 {
    575     if (!makeContextCurrent())
    576         return;
    577     LOG(WebGL, "Detected a mux switch or display reconfiguration. Call CGLUpdateContext. (%p)", this);
    578 
    579     EGLDeviceEXT device = nullptr;
    580     EGL_QueryDisplayAttribEXT(m_displayObj, EGL_DEVICE_EXT, reinterpret_cast<EGLAttrib*>(&device));
    581     CGLContextObj cglContext = nullptr;
    582     EGL_QueryDeviceAttribEXT(device, EGL_CGL_CONTEXT_ANGLE, reinterpret_cast<EGLAttrib*>(&cglContext));
    583 
    584     CGLUpdateContext(cglContext);
    585     m_hasSwitchedToHighPerformanceGPU = true;
    586 }
    587 #endif
     490    if (contextAttributes().powerPreference != GraphicsContextGLPowerPreference::HighPerformance)
     491        return;
     492    if (isVisible)
     493        m_highPerformanceGPURequest = ScopedHighPerformanceGPURequest::acquire();
     494    else
     495        m_highPerformanceGPURequest = { };
     496#else
     497    UNUSED_PARAM(isVisible);
     498#endif
     499}
     500
     501void GraphicsContextGLOpenGL::displayWasReconfigured()
     502{
     503#if PLATFORM(MAC)
     504    if (m_supportsPowerPreference)
     505        EGL_HandleGPUSwitchANGLE(m_displayObj);
     506#endif
     507    dispatchContextChangedNotification();
     508}
    588509
    589510bool GraphicsContextGLOpenGL::reshapeDisplayBufferBacking()
     
    655576void GraphicsContextGLOpenGL::simulateContextChanged()
    656577{
    657     GraphicsContextGLOpenGLManager::sharedManager().updateAllContexts();
    658 }
    659 
    660 bool GraphicsContextGLOpenGL::allowOfflineRenderers() const
    661 {
    662 #if PLATFORM(MAC) && ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
    663     // When WindowServer access is blocked in the WebProcess, there is no way
    664     // for OpenGL to decide which GPU is connected to a display (online/offline).
    665     // OpenGL will then consider all GPUs, or renderers, as offline, which means
    666     // all offline renderers need to be considered when finding a pixel format.
    667     // In WebKit legacy, there will still be a WindwServer connection, and
    668     // m_displayMask will not be set in this case.
    669     if (primaryOpenGLDisplayMask())
    670         return true;
    671 #elif PLATFORM(MACCATALYST)
    672     // FIXME: <rdar://53062794> We're very inconsistent about WEBPROCESS_WINDOWSERVER_BLOCKING
    673     // and MAC/MACCATALYST and OPENGL/OPENGLES.
    674     return true;
    675 #endif
    676        
    677 #if HAVE(APPLE_GRAPHICS_CONTROL)
    678     if (hasLowAndHighPowerGPUs())
    679         return true;
    680 #endif
    681    
    682     return false;
    683 }
    684 
    685 #if PLATFORM(MAC)
    686 void GraphicsContextGLOpenGL::screenDidChange(PlatformDisplayID displayID)
    687 {
    688     if (!m_contextObj)
    689         return;
    690     if (!m_hasSwitchedToHighPerformanceGPU) {
    691         EGLDeviceEXT device = nullptr;
    692         EGL_QueryDisplayAttribEXT(m_displayObj, EGL_DEVICE_EXT, reinterpret_cast<EGLAttrib*>(&device));
    693         CGLContextObj cglContext = nullptr;
    694         CGLPixelFormatObj pixelFormat = nullptr;
    695         EGL_QueryDeviceAttribEXT(device, EGL_CGL_CONTEXT_ANGLE, reinterpret_cast<EGLAttrib*>(&cglContext));
    696         EGL_QueryDeviceAttribEXT(device, EGL_CGL_PIXEL_FORMAT_ANGLE, reinterpret_cast<EGLAttrib*>(&pixelFormat));
    697         setGPUByRegistryID(cglContext, pixelFormat, gpuIDForDisplay(displayID));
    698     }
    699 }
    700 #endif // !PLATFORM(MAC)
     578    GraphicsContextGLOpenGLManager::sharedManager().displayWasReconfigured();
     579}
    701580
    702581void GraphicsContextGLOpenGL::prepareForDisplay()
  • trunk/Source/WebCore/platform/graphics/mac/GraphicsChecksMac.h

    r271879 r271880  
    11/*
    2  * Copyright (C) 2018 Apple Inc. All rights reserved.
     2 * Copyright (C) 2021 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2626#pragma once
    2727
    28 #include <WebCore/SwitchingGPUClient.h>
     28namespace WebCore {
    2929
    30 namespace WebKit {
    31 
    32 class WebSwitchingGPUClient : public WebCore::SwitchingGPUClient {
    33 public:
    34     static WebSwitchingGPUClient& singleton();
    35    
    36     void requestHighPerformanceGPU() override;
    37     void releaseHighPerformanceGPU() override;
    38 };
     30WEBCORE_EXPORT bool hasLowAndHighPowerGPUs();
    3931
    4032}
  • trunk/Source/WebCore/platform/graphics/mac/ScopedHighPerformanceGPURequest.h

    r271879 r271880  
    11/*
    2  * Copyright (C) 2018 Apple Inc. All rights reserved.
     2 * Copyright (C) 2021 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2626#pragma once
    2727
     28#include "GraphicsChecksMac.h"
     29#include "SwitchingGPUClient.h"
     30
    2831namespace WebCore {
    2932
    30 class SwitchingGPUClient {
     33class ScopedHighPerformanceGPURequest {
    3134public:
    32     WEBCORE_EXPORT static SwitchingGPUClient* singletonIfExists();
    33     WEBCORE_EXPORT static void setSingleton(SwitchingGPUClient&);
    34 
    35     virtual ~SwitchingGPUClient() = default;
    36 
    37     virtual void requestHighPerformanceGPU() = 0;
    38     virtual void releaseHighPerformanceGPU() = 0;
    39    
     35    ScopedHighPerformanceGPURequest() = default;
     36    ScopedHighPerformanceGPURequest(ScopedHighPerformanceGPURequest&& other)
     37        : m_requested(std::exchange(other.m_requested, false))
     38    {
     39    }
     40    ~ScopedHighPerformanceGPURequest()
     41    {
     42        if (!m_requested)
     43            return;
     44        SwitchingGPUClient::singletonIfExists()->releaseHighPerformanceGPU();
     45    }
     46    ScopedHighPerformanceGPURequest& operator=(ScopedHighPerformanceGPURequest&& other)
     47    {
     48        if (m_requested)
     49            SwitchingGPUClient::singletonIfExists()->releaseHighPerformanceGPU();
     50        m_requested = std::exchange(other.m_requested, false);
     51        return *this;
     52    }
     53    static ScopedHighPerformanceGPURequest acquire()
     54    {
     55        if (!hasLowAndHighPowerGPUs())
     56            return { };
     57        auto client = SwitchingGPUClient::singletonIfExists();
     58        if (!client)
     59            return { };
     60        client->requestHighPerformanceGPU();
     61        return { DidRequest };
     62    }
    4063private:
    41     static SwitchingGPUClient* m_singleton;
     64    enum RequestState { DidRequest };
     65    ScopedHighPerformanceGPURequest(RequestState)
     66        : m_requested(true)
     67    {
     68    }
     69    bool m_requested { false };
    4270};
    4371
  • trunk/Source/WebCore/platform/graphics/mac/SwitchingGPUClient.h

    r262811 r271880  
    3030class SwitchingGPUClient {
    3131public:
    32     WEBCORE_EXPORT static SwitchingGPUClient* singletonIfExists();
    3332    WEBCORE_EXPORT static void setSingleton(SwitchingGPUClient&);
    3433
    3534    virtual ~SwitchingGPUClient() = default;
    36 
     35private:
     36    WEBCORE_EXPORT static SwitchingGPUClient* singletonIfExists();
    3737    virtual void requestHighPerformanceGPU() = 0;
    3838    virtual void releaseHighPerformanceGPU() = 0;
    39    
    40 private:
     39
    4140    static SwitchingGPUClient* m_singleton;
     41    friend class ScopedHighPerformanceGPURequest;
    4242};
    4343
  • trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGL.h

    r271679 r271880  
    6868class GCGLLayer;
    6969}
     70#endif
     71
     72#if PLATFORM(MAC)
     73#include "ScopedHighPerformanceGPURequest.h"
    7074#endif
    7175
     
    257261    void texSubImage2D(GCGLenum target, GCGLint level, GCGLint xoffset, GCGLint yoffset, GCGLsizei width, GCGLsizei height, GCGLenum format, GCGLenum type, GCGLintptr offset) final;
    258262    void compressedTexImage2D(GCGLenum target, GCGLint level, GCGLenum internalformat, GCGLsizei width, GCGLsizei height, GCGLint border, GCGLsizei imageSize, GCGLSpan<const GCGLvoid> data) final;
    259     void compressedTexImage2D(GCGLenum target, GCGLint level, GCGLenum internalformat, GCGLsizei width, GCGLsizei height, GCGLint border, GCGLsizei imageSize, GCGLintptr offset) final; 
     263    void compressedTexImage2D(GCGLenum target, GCGLint level, GCGLenum internalformat, GCGLsizei width, GCGLsizei height, GCGLint border, GCGLsizei imageSize, GCGLintptr offset) final;
    260264    void compressedTexSubImage2D(GCGLenum target, GCGLint level, GCGLint xoffset, GCGLint yoffset, GCGLsizei width, GCGLsizei height, GCGLenum format, GCGLsizei imageSize, GCGLSpan<const GCGLvoid> data) final;
    261265    void compressedTexSubImage2D(GCGLenum target, GCGLint level, GCGLint xoffset, GCGLint yoffset, GCGLsizei width, GCGLsizei height, GCGLenum format, GCGLsizei imageSize, GCGLintptr offset) final;
     
    462466#endif
    463467
    464 #if PLATFORM(COCOA) && PLATFORM(MAC)
    465     void updateCGLContext();
     468#if PLATFORM(COCOA)
     469    void displayWasReconfigured();
    466470#endif
    467471
    468472    void setContextVisibility(bool) final;
    469 
    470     GraphicsContextGLPowerPreference powerPreferenceUsedForCreation() const final { return m_powerPreferenceUsedForCreation; }
    471473
    472474    // Support for buffer creation and deletion
     
    498500    unsigned textureSeed(GCGLuint texture) { return m_state.textureSeedCount.count(texture); }
    499501
    500 #if PLATFORM(MAC)
    501     using PlatformDisplayID = uint32_t;
    502     void screenDidChange(PlatformDisplayID);
    503 #endif
    504 
    505502    void prepareForDisplay() final;
    506503
     
    530527    void validateDepthStencil(const char* packedDepthStencilExtension);
    531528    void validateAttributes();
    532    
     529
    533530    void readnPixelsImpl(GCGLint x, GCGLint y, GCGLsizei width, GCGLsizei height, GCGLenum format, GCGLenum type, GCGLsizei bufSize, GCGLsizei* length, GCGLsizei* columns, GCGLsizei* rows, GCGLvoid* data, bool readingToPixelBufferObject);
    534531
     
    548545
    549546#if PLATFORM(COCOA)
    550     bool allowOfflineRenderers() const;
    551547    bool reshapeDisplayBufferBacking();
    552548    bool allocateAndBindDisplayBufferBacking();
     
    584580        {
    585581        }
    586        
     582
    587583        ShaderSymbolMap& symbolMap(enum ANGLEShaderSymbolType symbolType)
    588584        {
     
    649645#endif
    650646
    651     GraphicsContextGLPowerPreference m_powerPreferenceUsedForCreation { GraphicsContextGLPowerPreference::Default };
    652647    Vector<Vector<float>> m_vertexArray;
    653648
     
    681676        using BoundTextureMap = HashMap<GCGLenum,
    682677            std::pair<GCGLuint, GCGLenum>,
    683             WTF::IntHash<GCGLenum>, 
     678            WTF::IntHash<GCGLenum>,
    684679            WTF::UnsignedWithZeroKeyHashTraits<GCGLuint>,
    685680            WTF::PairHashTraits<WTF::UnsignedWithZeroKeyHashTraits<GCGLuint>, WTF::UnsignedWithZeroKeyHashTraits<GCGLuint>>
     
    762757    std::unique_ptr<IOSurface> m_displayBufferBacking;
    763758    void* m_displayBufferPbuffer { nullptr };
    764 
    765     bool m_hasSwitchedToHighPerformanceGPU { false };
     759#endif
     760#if PLATFORM(MAC)
     761    bool m_supportsPowerPreference { false };
     762    ScopedHighPerformanceGPURequest m_highPerformanceGPURequest;
    766763#endif
    767764#if ENABLE(VIDEO) && USE(AVFOUNDATION)
  • trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLManager.cpp

    r270477 r271880  
    3232#include "Logging.h"
    3333
    34 #if HAVE(APPLE_GRAPHICS_CONTROL)
    35 #include <sys/sysctl.h>
    36 #endif
    37 
    38 #if PLATFORM(MAC)
    39 #include "SwitchingGPUClient.h"
    40 #endif
    41 
    4234namespace WebCore {
    43 
    44 #if HAVE(APPLE_GRAPHICS_CONTROL)
    45 
    46 enum {
    47     kAGCOpen,
    48     kAGCClose
    49 };
    50 
    51 static io_connect_t attachToAppleGraphicsControl()
    52 {
    53     mach_port_t masterPort = MACH_PORT_NULL;
    54    
    55     if (IOMasterPort(MACH_PORT_NULL, &masterPort) != KERN_SUCCESS)
    56         return MACH_PORT_NULL;
    57    
    58     CFDictionaryRef classToMatch = IOServiceMatching("AppleGraphicsControl");
    59     if (!classToMatch)
    60         return MACH_PORT_NULL;
    61    
    62     kern_return_t kernResult;
    63     io_iterator_t iterator;
    64     if ((kernResult = IOServiceGetMatchingServices(masterPort, classToMatch, &iterator)) != KERN_SUCCESS)
    65         return MACH_PORT_NULL;
    66    
    67     io_service_t serviceObject = IOIteratorNext(iterator);
    68     IOObjectRelease(iterator);
    69     if (!serviceObject)
    70         return MACH_PORT_NULL;
    71    
    72     io_connect_t dataPort;
    73     IOObjectRetain(serviceObject);
    74     kernResult = IOServiceOpen(serviceObject, mach_task_self(), 0, &dataPort);
    75     IOObjectRelease(serviceObject);
    76    
    77     return (kernResult == KERN_SUCCESS) ? dataPort : MACH_PORT_NULL;
    78 }
    79 
    80 static bool hasMuxCapability()
    81 {
    82     io_connect_t dataPort = attachToAppleGraphicsControl();
    83    
    84     if (dataPort == MACH_PORT_NULL)
    85         return false;
    86    
    87     bool result;
    88     if (IOConnectCallScalarMethod(dataPort, kAGCOpen, nullptr, 0, nullptr, nullptr) == KERN_SUCCESS) {
    89         IOConnectCallScalarMethod(dataPort, kAGCClose, nullptr, 0, nullptr, nullptr);
    90         result = true;
    91     } else
    92         result = false;
    93    
    94     IOServiceClose(dataPort);
    95    
    96     if (result) {
    97         // This is detecting Mac hardware with an Intel g575 GPU, which
    98         // we don't want to make available to muxing.
    99         // Based on information from Apple's OpenGL team, such devices
    100         // have four or fewer processors.
    101         // <rdar://problem/30060378>
    102         int names[2] = { CTL_HW, HW_NCPU };
    103         int cpuCount;
    104         size_t cpuCountLength = sizeof(cpuCount);
    105         sysctl(names, 2, &cpuCount, &cpuCountLength, nullptr, 0);
    106         result = cpuCount > 4;
    107     }
    108    
    109     return result;
    110 }
    111 
    112 bool hasLowAndHighPowerGPUs()
    113 {
    114     static bool canMux = hasMuxCapability();
    115     return canMux;
    116 }
    117 #endif // HAVE(APPLE_GRAPHICS_CONTROL)
    11835
    11936GraphicsContextGLOpenGLManager& GraphicsContextGLOpenGLManager::sharedManager()
     
    12845    LOG(WebGL, "GraphicsContextGLOpenGLManager::displayWasReconfigured");
    12946    if (flags & kCGDisplaySetModeFlag)
    130         GraphicsContextGLOpenGLManager::sharedManager().updateAllContexts();
     47        GraphicsContextGLOpenGLManager::sharedManager().displayWasReconfigured();
    13148}
    13249#endif
    13350
    134 void GraphicsContextGLOpenGLManager::updateAllContexts()
     51#if PLATFORM(COCOA)
     52void GraphicsContextGLOpenGLManager::displayWasReconfigured()
    13553{
    136 #if PLATFORM(MAC)
    137     for (const auto& context : m_contexts) {
    138         context->updateCGLContext();
    139         context->dispatchContextChangedNotification();
    140     }
    141 #endif
    142 }
    143 
    144 #if PLATFORM(MAC)
    145 void GraphicsContextGLOpenGLManager::screenDidChange(PlatformDisplayID displayID, const HostWindow* window)
    146 {
    147     for (const auto& contextAndWindow : m_contextWindowMap) {
    148         if (contextAndWindow.value == window) {
    149             contextAndWindow.key->screenDidChange(displayID);
    150             LOG(WebGL, "Changing context (%p) to display (%d).", contextAndWindow.key, displayID);
    151         }
    152     }
     54    for (const auto& context : m_contexts)
     55        context->displayWasReconfigured();
    15356}
    15457#endif
    15558
    156 void GraphicsContextGLOpenGLManager::addContext(GraphicsContextGLOpenGL* context, HostWindow* window)
     59void GraphicsContextGLOpenGLManager::addContext(GraphicsContextGLOpenGL* context)
    15760{
    15861    ASSERT(context);
     
    16770    ASSERT(!m_contexts.contains(context));
    16871    m_contexts.append(context);
    169     m_contextWindowMap.set(context, window);
    17072}
    17173
     
    17577        return;
    17678    m_contexts.removeFirst(context);
    177     m_contextWindowMap.remove(context);
    178     removeContextRequiringHighPerformance(context);
    179    
    18079#if PLATFORM(MAC) && !ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
    18180    if (!m_contexts.size())
    18281        CGDisplayRemoveReconfigurationCallback(displayWasReconfigured, nullptr);
    183 #endif
    184 }
    185 
    186 HostWindow* GraphicsContextGLOpenGLManager::hostWindowForContext(GraphicsContextGLOpenGL* context) const
    187 {
    188     ASSERT(m_contextWindowMap.contains(context));
    189     return m_contextWindowMap.get(context);
    190 }
    191 
    192 void GraphicsContextGLOpenGLManager::addContextRequiringHighPerformance(GraphicsContextGLOpenGL* context)
    193 {
    194     ASSERT(context);
    195     if (!context)
    196         return;
    197    
    198     ASSERT(m_contexts.contains(context));
    199     ASSERT(!m_contextsRequiringHighPerformance.contains(context));
    200    
    201     LOG(WebGL, "This context (%p) requires the high-performance GPU.", context);
    202     m_contextsRequiringHighPerformance.add(context);
    203    
    204     updateHighPerformanceState();
    205 }
    206 
    207 void GraphicsContextGLOpenGLManager::removeContextRequiringHighPerformance(GraphicsContextGLOpenGL* context)
    208 {
    209     if (!context)
    210         return;
    211 
    212     if (!m_contextsRequiringHighPerformance.contains(context))
    213         return;
    214    
    215     LOG(WebGL, "This context (%p) no longer requires the high-performance GPU.", context);
    216     m_contextsRequiringHighPerformance.remove(context);
    217    
    218     updateHighPerformanceState();
    219 }
    220 
    221 void GraphicsContextGLOpenGLManager::updateHighPerformanceState()
    222 {
    223 #if PLATFORM(MAC)
    224     if (!hasLowAndHighPowerGPUs())
    225         return;
    226    
    227     if (m_contextsRequiringHighPerformance.size()) {
    228        
    229         if (m_disableHighPerformanceGPUTimer.isActive()) {
    230             LOG(WebGL, "Cancel pending timer for turning off high-performance GPU.");
    231             m_disableHighPerformanceGPUTimer.stop();
    232         }
    233 
    234         if (!m_requestingHighPerformance) {
    235             LOG(WebGL, "Request the high-performance GPU.");
    236             m_requestingHighPerformance = true;
    237             if (auto* singleton = SwitchingGPUClient::singletonIfExists())
    238                 singleton->requestHighPerformanceGPU();
    239         }
    240 
    241     } else {
    242         // Don't immediately turn off the high-performance GPU. The user might be
    243         // swapping back and forth between tabs or windows, and we don't want to cause
    244         // churn if we can avoid it.
    245         if (!m_disableHighPerformanceGPUTimer.isActive()) {
    246             LOG(WebGL, "Set a timer to release the high-performance GPU.");
    247             // FIXME: Expose this value as a Setting, which would require this class
    248             // to reference a frame, page or document.
    249             static const Seconds timeToKeepHighPerformanceGPUAlive { 10_s };
    250             m_disableHighPerformanceGPUTimer.startOneShot(timeToKeepHighPerformanceGPUAlive);
    251         }
    252     }
    253 #endif
    254 }
    255 
    256 void GraphicsContextGLOpenGLManager::disableHighPerformanceGPUTimerFired()
    257 {
    258     if (m_contextsRequiringHighPerformance.size())
    259         return;
    260 
    261     m_requestingHighPerformance = false;
    262 #if PLATFORM(MAC)
    263     if (auto* singleton = SwitchingGPUClient::singletonIfExists())
    264         singleton->releaseHighPerformanceGPU();
    26582#endif
    26683}
  • trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLManager.h

    r268198 r271880  
    2626#pragma once
    2727
    28 #include "Timer.h"
    29 #include <wtf/HashMap.h>
    3028#include <wtf/HashSet.h>
    3129
     
    3937
    4038class GraphicsContextGLOpenGL;
    41 class HostWindow;
    42 
    43 using PlatformDisplayID = uint32_t;
    44 
    45 #if HAVE(APPLE_GRAPHICS_CONTROL)
    46 WEBCORE_EXPORT bool hasLowAndHighPowerGPUs();
    47 #endif
    4839
    4940class GraphicsContextGLOpenGLManager {
     
    5243    static GraphicsContextGLOpenGLManager& sharedManager();
    5344   
    54     void addContext(GraphicsContextGLOpenGL*, HostWindow*);
     45    void addContext(GraphicsContextGLOpenGL*);
    5546    void removeContext(GraphicsContextGLOpenGL*);
    56 
    57     HostWindow* hostWindowForContext(GraphicsContextGLOpenGL*) const;
    58    
    59     void addContextRequiringHighPerformance(GraphicsContextGLOpenGL*);
    60     void removeContextRequiringHighPerformance(GraphicsContextGLOpenGL*);
    6147   
    6248    void recycleContextIfNecessary();
    6349    bool hasTooManyContexts() const { return m_contexts.size() >= MaxContexts; }
    6450   
    65     void updateAllContexts();
    66 
    6751#if PLATFORM(MAC)
    68     void screenDidChange(PlatformDisplayID, const HostWindow*);
    6952    WEBCORE_EXPORT static void displayWasReconfigured(CGDirectDisplayID, CGDisplayChangeSummaryFlags, void*);
     53#endif
     54#if PLATFORM(COCOA)
     55    void displayWasReconfigured();
    7056#endif
    7157   
    7258private:
    73     GraphicsContextGLOpenGLManager()
    74         : m_disableHighPerformanceGPUTimer(*this, &GraphicsContextGLOpenGLManager::disableHighPerformanceGPUTimerFired)
    75     {
    76     }
    77 
    78     void updateHighPerformanceState();
    79     void disableHighPerformanceGPUTimerFired();
     59    GraphicsContextGLOpenGLManager() = default;
    8060
    8161    Vector<GraphicsContextGLOpenGL*> m_contexts;
    82     HashMap<GraphicsContextGLOpenGL*, HostWindow*> m_contextWindowMap;
    83     HashSet<GraphicsContextGLOpenGL*> m_contextsRequiringHighPerformance;
    84    
    85     Timer m_disableHighPerformanceGPUTimer;
    86     bool m_requestingHighPerformance { false };
    8762};
    8863
  • trunk/Source/WebCore/testing/Internals.cpp

    r271806 r271880  
    322322
    323323#if PLATFORM(MAC)
    324 #include "GraphicsContextGLOpenGLManager.h"
     324#include "GraphicsChecksMac.h"
    325325#include "NSScrollerImpDetails.h"
    326326#include "ScrollbarThemeMac.h"
  • trunk/Source/WebKit/ChangeLog

    r271879 r271880  
     12021-01-26  Kimmo Kinnunen  <kkinnunen@apple.com>
     2
     3        WebGL power preference and discrete/internal gpu selection implemented incorrectly with ANGLE
     4        https://bugs.webkit.org/show_bug.cgi?id=220843
     5
     6        Reviewed by Dean Jackson.
     7
     8        Move the high-performance GPU shutdown timer from individual web processes to the main class
     9        in the ui process. This simplifies the implementation and reduces the number of timers.
     10
     11        * UIProcess/mac/HighPerformanceGPUManager.h:
     12        * UIProcess/mac/HighPerformanceGPUManager.mm:
     13        (WebKit::HighPerformanceGPUManager::HighPerformanceGPUManager):
     14        (WebKit::HighPerformanceGPUManager::removeProcessRequiringHighPerformance):
     15        (WebKit::HighPerformanceGPUManager::updateState):
     16        * WebProcess/WebCoreSupport/mac/WebSwitchingGPUClient.cpp:
     17        (WebKit::WebSwitchingGPUClient::requestHighPerformanceGPU):
     18        (WebKit::WebSwitchingGPUClient::releaseHighPerformanceGPU):
     19        * WebProcess/WebCoreSupport/mac/WebSwitchingGPUClient.h:
     20
    1212021-01-26  Carlos Garcia Campos  <cgarcia@igalia.com>
    222
  • trunk/Source/WebKit/UIProcess/mac/HighPerformanceGPUManager.h

    r236773 r271880  
    2929
    3030#include <OpenGL/CGLTypes.h>
     31#include <WebCore/Timer.h>
    3132#include <wtf/HashSet.h>
    3233#include <wtf/NeverDestroyed.h>
     
    4546
    4647private:
    47     HighPerformanceGPUManager() = default;
     48    HighPerformanceGPUManager();
    4849    ~HighPerformanceGPUManager();
    49 
    5050    void updateState();
    5151
    5252    HashSet<WebProcessProxy*> m_processesRequiringHighPerformance;
    5353    CGLPixelFormatObj m_pixelFormatObj { nullptr };
     54    WebCore::Timer m_updateStateTimer;
    5455};
    5556
  • trunk/Source/WebKit/UIProcess/mac/HighPerformanceGPUManager.mm

    r269118 r271880  
    3030
    3131#include "Logging.h"
    32 #include <WebCore/GraphicsContextGLOpenGLManager.h>
     32#include <WebCore/GraphicsChecksMac.h>
    3333#include <WebCore/OpenGLSoftLinkCocoa.h>
    3434
     
    4444    return sharedManager;
    4545}
     46
     47HighPerformanceGPUManager::HighPerformanceGPUManager()
     48    : m_updateStateTimer(*this, &HighPerformanceGPUManager::updateState)
     49{
     50}
     51
     52HighPerformanceGPUManager::~HighPerformanceGPUManager() = default;
    4653
    4754void HighPerformanceGPUManager::addProcessRequiringHighPerformance(WebProcessProxy* process)
     
    6673    if (m_processesRequiringHighPerformance.remove(process)) {
    6774        LOG(WebGL, "HighPerformanceGPUManager::removeProcessRequiringHighPerformance() - removing process %p", process);
    68         updateState();
     75        static const Seconds timeToKeepHighPerformanceGPUAlive { 10_s };
     76        m_updateStateTimer.startOneShot(timeToKeepHighPerformanceGPUAlive);
    6977        return;
    7078    }
     
    7583void HighPerformanceGPUManager::updateState()
    7684{
     85    if (m_updateStateTimer.isActive())
     86        m_updateStateTimer.stop();
    7787    if (m_processesRequiringHighPerformance.size()) {
    7888        if (!m_pixelFormatObj) {
  • trunk/Source/WebKit/WebProcess/WebCoreSupport/mac/WebSwitchingGPUClient.cpp

    r236773 r271880  
    4444void WebSwitchingGPUClient::requestHighPerformanceGPU()
    4545{
     46    m_requests++;
     47    if (m_requests != 1)
     48        return;
    4649    LOG(WebGL, "WebSwitchingGPUClient::requestHighPerformanceGPU() from WebProcess");
    4750    WebProcess::singleton().parentProcessConnection()->send(Messages::WebProcessProxy::RequestHighPerformanceGPU(), 0);
     
    5053void WebSwitchingGPUClient::releaseHighPerformanceGPU()
    5154{
     55    ASSERT(m_requests);
     56    m_requests--;
     57    if (m_requests)
     58        return;
    5259    LOG(WebGL, "WebSwitchingGPUClient::releaseHighPerformanceGPU() from WebProcess");
    5360    WebProcess::singleton().parentProcessConnection()->send(Messages::WebProcessProxy::ReleaseHighPerformanceGPU(), 0);
  • trunk/Source/WebKit/WebProcess/WebCoreSupport/mac/WebSwitchingGPUClient.h

    r236773 r271880  
    3333public:
    3434    static WebSwitchingGPUClient& singleton();
    35    
     35private:
    3636    void requestHighPerformanceGPU() override;
    3737    void releaseHighPerformanceGPU() override;
     38    unsigned m_requests { 0 };
    3839};
    3940
Note: See TracChangeset for help on using the changeset viewer.