Changeset 230015 in webkit


Ignore:
Timestamp:
Mar 27, 2018, 4:39:40 PM (7 years ago)
Author:
pvollan@apple.com
Message:

The layout test fast/canvas/webgl/read-pixels-test.html is timing out.
https://bugs.webkit.org/show_bug.cgi?id=183923
<rdar://problem/38756869>

Reviewed by Brent Fulgham.

Source/WebCore:

The test is timing out when we do not interact directly with the WindowServer, causing
OpenGL to fall back to software rendering. In this mode, any call to CGLChoosePixelFormat
requesting an accelerated pixel format will fail because it cannot determine which GPU is
connected to the display.

OpenGL treats all GPUs as if they were offline when used in a process (like the WebContent
process) that does not directly control the display.

We can get correct behavior if we tell OpenGL which GPU is currently connected to the
display, and if we instruct CGLChoosePixelFormat to create an offline renderer pixel format
by including the 'kCGLPFAAllowOfflineRenderers' flag in its arguments.

We can use CGLSetVirtualScreen with an OpenGL display mask that tells the OpenGL framework
which GPU it should use.

See https://developer.apple.com/library/content/technotes/tn2229/_index.html#//apple_ref/doc/uid/DTS40008924-CH1-SUBSECTION7
for details on how the virtual screen is found from the OpenGL display mask.

No new tests, covered by existing tests.

  • WebCore.xcodeproj/project.pbxproj:
  • platform/graphics/GraphicsContext3D.h:
  • platform/graphics/cocoa/GraphicsContext3DCocoa.mm:

(WebCore::setPixelFormat):
(WebCore::identifyAndSetCurrentGPU):
(WebCore::GraphicsContext3D::GraphicsContext3D):
(WebCore::GraphicsContext3D::setOpenGLDisplayMask):
(WebCore::GraphicsContext3D::allowOfflineRenderers):

Source/WebKit:

Send OpenGL display mask to the WebContent process when the display ID is changing.

  • UIProcess/WebPageProxy.cpp:

(WebKit::WebPageProxy::windowScreenDidChange):

  • WebProcess/WebPage/WebPage.h:
  • WebProcess/WebPage/WebPage.messages.in:
  • WebProcess/WebPage/mac/WebPageMac.mm:

(WebKit::WebPage::openGLDisplayMaskChanged):

Source/WTF:

Add compile guard for blocking of the WindowServer in the WebProcess.

  • wtf/FeatureDefines.h:
Location:
trunk/Source
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WTF/ChangeLog

    r229990 r230015  
     12018-03-27  Per Arne Vollan  <pvollan@apple.com>
     2
     3        The layout test fast/canvas/webgl/read-pixels-test.html is timing out.
     4        https://bugs.webkit.org/show_bug.cgi?id=183923
     5        <rdar://problem/38756869>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        Add compile guard for blocking of the WindowServer in the WebProcess.
     10
     11        * wtf/FeatureDefines.h:
     12
    1132018-03-26  Tim Horton  <timothy_horton@apple.com>
    214
  • trunk/Source/WTF/wtf/FeatureDefines.h

    r229961 r230015  
    232232#endif
    233233
     234#if !defined(ENABLE_WEBPROCESS_WINDOWSERVER_BLOCKING)
     235#define ENABLE_WEBPROCESS_WINDOWSERVER_BLOCKING 0
     236#endif
     237
    234238#endif /* PLATFORM(MAC) */
    235239
  • trunk/Source/WebCore/ChangeLog

    r230012 r230015  
     12018-03-27  Per Arne Vollan  <pvollan@apple.com>
     2
     3        The layout test fast/canvas/webgl/read-pixels-test.html is timing out.
     4        https://bugs.webkit.org/show_bug.cgi?id=183923
     5        <rdar://problem/38756869>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        The test is timing out when we do not interact directly with the WindowServer, causing
     10        OpenGL to fall back to software rendering. In this mode, any call to CGLChoosePixelFormat
     11        requesting an accelerated pixel format will fail because it cannot determine which GPU is
     12        connected to the display.
     13
     14        OpenGL treats all GPUs as if they were offline when used in a process (like the WebContent
     15        process) that does not directly control the display.
     16
     17        We can get correct behavior if we tell OpenGL which GPU is currently connected to the
     18        display, and if we instruct CGLChoosePixelFormat to create an offline renderer pixel format
     19        by including the 'kCGLPFAAllowOfflineRenderers' flag in its arguments.
     20
     21        We can use CGLSetVirtualScreen with an OpenGL display mask that tells the OpenGL framework
     22        which GPU it should use.
     23
     24        See https://developer.apple.com/library/content/technotes/tn2229/_index.html#//apple_ref/doc/uid/DTS40008924-CH1-SUBSECTION7
     25        for details on how the virtual screen is found from the OpenGL display mask.
     26
     27        No new tests, covered by existing tests.
     28
     29        * WebCore.xcodeproj/project.pbxproj:
     30        * platform/graphics/GraphicsContext3D.h:
     31        * platform/graphics/cocoa/GraphicsContext3DCocoa.mm:
     32        (WebCore::setPixelFormat):
     33        (WebCore::identifyAndSetCurrentGPU):
     34        (WebCore::GraphicsContext3D::GraphicsContext3D):
     35        (WebCore::GraphicsContext3D::setOpenGLDisplayMask):
     36        (WebCore::GraphicsContext3D::allowOfflineRenderers):
     37
    1382018-03-27  Jiewen Tan  <jiewen_tan@apple.com>
    239
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r230012 r230015  
    12241224                46FCB6181A70820E00C5A21E /* DiagnosticLoggingKeys.h in Headers */ = {isa = PBXBuildFile; fileRef = CD37B37515C1A7E1006DC898 /* DiagnosticLoggingKeys.h */; settings = {ATTRIBUTES = (Private, ); }; };
    12251225                490707E61219C04300D90E51 /* ANGLEWebKitBridge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 490707E41219C04300D90E51 /* ANGLEWebKitBridge.cpp */; };
    1226                 490707E71219C04300D90E51 /* ANGLEWebKitBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = 490707E51219C04300D90E51 /* ANGLEWebKitBridge.h */; };
     1226                490707E71219C04300D90E51 /* ANGLEWebKitBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = 490707E51219C04300D90E51 /* ANGLEWebKitBridge.h */; settings = {ATTRIBUTES = (Private, ); }; };
    12271227                49291E4B134172C800E753DE /* ImageRenderingMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 49291E4A134172C800E753DE /* ImageRenderingMode.h */; };
    12281228                493E5E0912D6420500020081 /* PlatformCALayerClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 493E5E0812D6420500020081 /* PlatformCALayerClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    12711271                49C7B9E51042D32F0009D447 /* WebGLTexture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49C7B9C51042D32F0009D447 /* WebGLTexture.cpp */; };
    12721272                49C7B9E61042D32F0009D447 /* WebGLTexture.h in Headers */ = {isa = PBXBuildFile; fileRef = 49C7B9C61042D32F0009D447 /* WebGLTexture.h */; };
    1273                 49C7B9FC1042D3650009D447 /* GraphicsContext3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 49C7B9FB1042D3650009D447 /* GraphicsContext3D.h */; };
     1273                49C7B9FC1042D3650009D447 /* GraphicsContext3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 49C7B9FB1042D3650009D447 /* GraphicsContext3D.h */; settings = {ATTRIBUTES = (Private, ); }; };
    12741274                49D5DC2C0F423A73008F20FD /* Matrix3DTransformOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 49D5DC280F423A73008F20FD /* Matrix3DTransformOperation.h */; settings = {ATTRIBUTES = (Private, ); }; };
    12751275                49D5DC2E0F423A73008F20FD /* PerspectiveTransformOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 49D5DC2A0F423A73008F20FD /* PerspectiveTransformOperation.h */; settings = {ATTRIBUTES = (Private, ); }; };
  • trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h

    r229858 r230015  
    12831283    unsigned textureSeed(GC3Duint texture) { return m_state.textureSeedCount.count(texture); }
    12841284
     1285#if PLATFORM(MAC) && ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
     1286    WEBCORE_EXPORT static void setOpenGLDisplayMask(CGOpenGLDisplayMask);
     1287#endif
     1288
    12851289private:
    12861290    GraphicsContext3D(GraphicsContext3DAttributes, HostWindow*, RenderStyle = RenderOffscreen, GraphicsContext3D* sharedContext = nullptr);
     
    13151319    void resolveMultisamplingIfNecessary(const IntRect& = IntRect());
    13161320    void attachDepthAndStencilBufferIfNeeded(GLuint internalDepthStencilFormat, int width, int height);
     1321
     1322#if PLATFORM(COCOA)
     1323    bool allowOfflineRenderers() const;
     1324#endif
    13171325
    13181326    int m_currentWidth { 0 };
     
    14941502#endif
    14951503
     1504#if PLATFORM(MAC) && ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
     1505    static std::optional<CGOpenGLDisplayMask> m_displayMask;
     1506#endif
    14961507};
    14971508
  • trunk/Source/WebCore/platform/graphics/cocoa/GraphicsContext3DCocoa.mm

    r229906 r230015  
    6565static const unsigned statusCheckThreshold = 5;
    6666
     67#if PLATFORM(MAC) && ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
     68std::optional<CGOpenGLDisplayMask> GraphicsContext3D::m_displayMask;
     69#endif
     70
    6771#if HAVE(APPLE_GRAPHICS_CONTROL)
    6872
     
    317321#if USE(OPENGL)
    318322
    319 static void setPixelFormat(Vector<CGLPixelFormatAttribute>& attribs, int colorBits, int depthBits, bool accelerated, bool supersample, bool closest, bool antialias, bool useGLES3)
     323static void setPixelFormat(Vector<CGLPixelFormatAttribute>& attribs, int colorBits, int depthBits, bool accelerated, bool supersample, bool closest, bool antialias, bool useGLES3, bool allowOfflineRenderers)
    320324{
    321325    attribs.clear();
     
    330334    // system, and not force the discrete GPU.
    331335    // See https://developer.apple.com/library/mac/technotes/tn2229/_index.html
    332 #if HAVE(APPLE_GRAPHICS_CONTROL)
    333     if (hasMuxableGPU())
     336    if (allowOfflineRenderers)
    334337        attribs.append(kCGLPFAAllowOfflineRenderers);
    335 #endif
    336338
    337339    if (accelerated)
     
    397399    return context;
    398400}
     401
     402#if PLATFORM(MAC) && ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
     403static void identifyAndSetCurrentGPU(CGLPixelFormatObj pixelFormatObj, int numPixelFormats, CGOpenGLDisplayMask displayMaskOpenGL, PlatformGraphicsContext3D contextObj)
     404{
     405    // 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.
     406    // CGLSetVirtualScreen can be used to tell OpenGL which GPU it should be using.
     407    // See code example at https://developer.apple.com/library/content/technotes/tn2229/_index.html#//apple_ref/doc/uid/DTS40008924-CH1-SUBSECTION7
     408   
     409    if (!displayMaskOpenGL || !contextObj)
     410        return;
     411
     412    for (int virtualScreen = 0; virtualScreen < numPixelFormats; ++virtualScreen) {
     413        GLint displayMask = 0;
     414        CGLError error = CGLDescribePixelFormat(pixelFormatObj, virtualScreen, kCGLPFADisplayMask, &displayMask);
     415        ASSERT(error == kCGLNoError);
     416        if (error != kCGLNoError)
     417            continue;
     418        if (displayMask & displayMaskOpenGL) {
     419            error = CGLSetVirtualScreen(contextObj, virtualScreen);
     420            ASSERT(error == kCGLNoError);
     421            break;
     422        }
     423    }
     424}
     425#endif
    399426
    400427GraphicsContext3D::GraphicsContext3D(GraphicsContext3DAttributes attrs, HostWindow*, GraphicsContext3D::RenderStyle, GraphicsContext3D* sharedContext)
     
    439466#endif
    440467
    441     setPixelFormat(attribs, 32, 32, !attrs.forceSoftwareRenderer, true, false, useMultisampling, attrs.useGLES3);
     468    setPixelFormat(attribs, 32, 32, !attrs.forceSoftwareRenderer, true, false, useMultisampling, attrs.useGLES3, allowOfflineRenderers());
    442469    CGLChoosePixelFormat(attribs.data(), &pixelFormatObj, &numPixelFormats);
    443470
    444471    if (!numPixelFormats) {
    445         setPixelFormat(attribs, 32, 32, !attrs.forceSoftwareRenderer, false, false, useMultisampling, attrs.useGLES3);
     472        setPixelFormat(attribs, 32, 32, !attrs.forceSoftwareRenderer, false, false, useMultisampling, attrs.useGLES3, allowOfflineRenderers());
    446473        CGLChoosePixelFormat(attribs.data(), &pixelFormatObj, &numPixelFormats);
    447474
    448475        if (!numPixelFormats) {
    449             setPixelFormat(attribs, 32, 16, !attrs.forceSoftwareRenderer, false, false, useMultisampling, attrs.useGLES3);
     476            setPixelFormat(attribs, 32, 16, !attrs.forceSoftwareRenderer, false, false, useMultisampling, attrs.useGLES3, allowOfflineRenderers());
    450477            CGLChoosePixelFormat(attribs.data(), &pixelFormatObj, &numPixelFormats);
    451478
    452479            if (!attrs.forceSoftwareRenderer && !numPixelFormats) {
    453                 setPixelFormat(attribs, 32, 16, false, false, true, false, attrs.useGLES3);
     480                setPixelFormat(attribs, 32, 16, false, false, true, false, attrs.useGLES3, allowOfflineRenderers());
    454481                CGLChoosePixelFormat(attribs.data(), &pixelFormatObj, &numPixelFormats);
    455482                useMultisampling = false;
     
    464491    GLint abortOnBlacklist = 0;
    465492    CGLSetParameter(m_contextObj, kCGLCPAbortOnGPURestartStatusBlacklisted, &abortOnBlacklist);
     493   
     494#if PLATFORM(MAC) && ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
     495    if (m_displayMask.has_value())
     496        identifyAndSetCurrentGPU(pixelFormatObj, numPixelFormats, m_displayMask.value(), m_contextObj);
     497#endif
     498
    466499    CGLDestroyPixelFormat(pixelFormatObj);
    467500   
     
    757790}
    758791
     792#if PLATFORM(MAC) && ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
     793void GraphicsContext3D::setOpenGLDisplayMask(CGOpenGLDisplayMask displayMask)
     794{
     795    m_displayMask = displayMask;
     796}
     797#endif
     798
     799bool GraphicsContext3D::allowOfflineRenderers() const
     800{
     801#if PLATFORM(MAC) && ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
     802    // When WindowServer access is blocked in the WebProcess, there is no way
     803    // for OpenGL to decide which GPU is connected to a display (online/offline).
     804    // OpenGL will then consider all GPUs, or renderers, as offline, which means
     805    // all offline renderers need to be considered when finding a pixel format.
     806    // In WebKit legacy, there will still be a WindowServer connection, and
     807    // m_displayMask will not be set in this case.
     808    if (m_displayMask.has_value())
     809        return true;
     810#endif
     811       
     812#if HAVE(APPLE_GRAPHICS_CONTROL)
     813    if (hasMuxableGPU())
     814        return true;
     815#endif
     816   
     817    return false;
     818}
     819
    759820}
    760821
  • trunk/Source/WebKit/ChangeLog

    r230014 r230015  
     12018-03-27  Per Arne Vollan  <pvollan@apple.com>
     2
     3        The layout test fast/canvas/webgl/read-pixels-test.html is timing out.
     4        https://bugs.webkit.org/show_bug.cgi?id=183923
     5        <rdar://problem/38756869>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        Send OpenGL display mask to the WebContent process when the display ID is changing.
     10
     11        * UIProcess/WebPageProxy.cpp:
     12        (WebKit::WebPageProxy::windowScreenDidChange):
     13        * WebProcess/WebPage/WebPage.h:
     14        * WebProcess/WebPage/WebPage.messages.in:
     15        * WebProcess/WebPage/mac/WebPageMac.mm:
     16        (WebKit::WebPage::openGLDisplayMaskChanged):
     17
    1182018-03-27  Youenn Fablet  <youenn@apple.com>
    219
  • trunk/Source/WebKit/UIProcess/WebPageProxy.cpp

    r229926 r230015  
    26472647
    26482648    m_process->send(Messages::WebPage::WindowScreenDidChange(displayID), m_pageID);
     2649
     2650#if PLATFORM(MAC) && ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
     2651    auto currentDisplaymask = CGDisplayIDToOpenGLDisplayMask(displayID);
     2652    m_process->send(Messages::WebPage::OpenGLDisplayMaskChanged(currentDisplaymask), m_pageID);
     2653#endif
    26492654}
    26502655
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.h

    r229926 r230015  
    10651065#endif
    10661066
     1067#if PLATFORM(MAC) && ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
     1068    void openGLDisplayMaskChanged(uint32_t displayMask);
     1069#endif
     1070
    10671071private:
    10681072    WebPage(uint64_t pageID, WebPageCreationParameters&&);
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in

    r229926 r230015  
    509509    GetApplicationManifest(WebKit::CallbackID callbackID)
    510510#endif
     511
     512#if PLATFORM(MAC) && ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
     513    OpenGLDisplayMaskChanged(uint32_t displayMask)
     514#endif
    511515}
  • trunk/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm

    r229100 r230015  
    6767#import <WebCore/FrameView.h>
    6868#import <WebCore/GraphicsContext.h>
     69#import <WebCore/GraphicsContext3D.h>
    6970#import <WebCore/HTMLConverter.h>
    7071#import <WebCore/HTMLPlugInImageElement.h>
     
    11911192#endif
    11921193
     1194#if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
     1195void WebPage::openGLDisplayMaskChanged(uint32_t displayMask)
     1196{
     1197    GraphicsContext3D::setOpenGLDisplayMask(displayMask);
     1198}
     1199#endif
    11931200
    11941201} // namespace WebKit
Note: See TracChangeset for help on using the changeset viewer.