Modified: trunk/Source/WebCore/ChangeLog (275096 => 275097)
--- trunk/Source/WebCore/ChangeLog 2021-03-26 15:34:24 UTC (rev 275096)
+++ trunk/Source/WebCore/ChangeLog 2021-03-26 15:34:49 UTC (rev 275097)
@@ -1,3 +1,31 @@
+2021-03-26 Kimmo Kinnunen <[email protected]>
+
+ GraphicsContextGLOpenGL should avoid calling into ANGLE MakeCurrent
+ https://bugs.webkit.org/show_bug.cgi?id=223511
+
+ Reviewed by Kenneth Russell.
+
+ Avoid calling ANGLE MakeCurrent for contexts that are already current. Cache the current context pointer into a
+ global variable. Currently the code adds no locking. For the forseeable future, ANGLE does not support
+ simultaneous access from multiple threads.
+
+ The optimization can be done when run in WebContent process or in GPU process, but not when in WK1. This is because in WK1,
+ the 3rd party client may run arbitrary code in WebKit thread. This includes code that changes EAGL or AGL state.
+ This code might change the current context underneath WebKit. In WK1 mode, we already use "volatile context" feature of
+ ANGLE to reset the platform context on every EGL command. The command we use for this for normal GL commands is EGL_MakeCurrent.
+ Makes in-process WebGL faster in MotionMark triangles by 6300 -> 9800 pts
+ Makes GPU process WebGL faster in MotionMark triangles by 5300 -> 7000 pts
+
+ * platform/graphics/cocoa/GraphicsContextGLOpenGLCocoa.mm:
+ (WebCore::isCurrentContextPredictable):
+ (WebCore::InitializeEGLDisplay):
+ (WebCore::GraphicsContextGLOpenGL::~GraphicsContextGLOpenGL):
+ (WebCore::GraphicsContextGLOpenGL::makeContextCurrent):
+ (WebCore::GraphicsContextGLOpenGL::clearCurrentContext):
+ (WebCore::GraphicsContextGLOpenGL::releaseCurrentContext):
+ (WebCore::GraphicsContextGLOpenGL::checkGPUStatus):
+ * platform/graphics/opengl/GraphicsContextGLOpenGL.h:
+
2021-03-25 Antoine Quint <[email protected]>
Fix interpolation of the caret-color CSS property
Modified: trunk/Source/WebCore/platform/graphics/cocoa/GraphicsContextGLOpenGLCocoa.mm (275096 => 275097)
--- trunk/Source/WebCore/platform/graphics/cocoa/GraphicsContextGLOpenGLCocoa.mm 2021-03-26 15:34:24 UTC (rev 275096)
+++ trunk/Source/WebCore/platform/graphics/cocoa/GraphicsContextGLOpenGLCocoa.mm 2021-03-26 15:34:49 UTC (rev 275097)
@@ -49,6 +49,17 @@
namespace WebCore {
+// In isCurrentContextPredictable() == true case this variable is accessed in single-threaded manner.
+// In isCurrentContextPredictable() == false case this variable is accessed from multiple threads but always sequentially
+// and it always contains nullptr and nullptr is always written to it.
+static GraphicsContextGLOpenGL* currentContext;
+
+static bool isCurrentContextPredictable()
+{
+ static bool value = isInWebProcess() || isInGPUProcess();
+ return value;
+}
+
#if ASSERT_ENABLED
// Returns true if we have volatile context extension for the particular API or
// if the particular API is not used.
@@ -82,7 +93,7 @@
Vector<EGLint> displayAttributes;
// FIXME: This should come in from the GraphicsContextGLAttributes.
- bool shouldInitializeWithVolatileContextSupport = !(isInWebProcess() || isInGPUProcess());
+ bool shouldInitializeWithVolatileContextSupport = !isCurrentContextPredictable();
if (shouldInitializeWithVolatileContextSupport) {
// For WK1 type APIs we need to set "volatile platform context" for specific
// APIs, since client code will be able to override the thread-global context
@@ -373,10 +384,10 @@
EGL_DestroySurface(m_displayObj, contentsHandle);
}
if (m_contextObj) {
- EGL_MakeCurrent(m_displayObj, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ clearCurrentContext();
EGL_DestroyContext(m_displayObj, m_contextObj);
- }
-
+ } else
+ ASSERT(currentContext != this);
LOG(WebGL, "Destroyed a GraphicsContextGLOpenGL (%p).", this);
}
@@ -427,18 +438,28 @@
// The exception is the case when the context is used before reshaping.
if (!m_displayBufferBacking && !getInternalFramebufferSize().isEmpty())
return false;
- // ANGLE has an early out for case where nothing changes. Calling MakeCurrent
- // is important to set volatile platform context. See InitializeEGLDisplay().
+ if (currentContext == this)
+ return true;
+ // Calling MakeCurrent is important to set volatile platform context. See InitializeEGLDisplay().
if (!EGL_MakeCurrent(m_displayObj, EGL_NO_SURFACE, EGL_NO_SURFACE, m_contextObj))
return false;
+ if (isCurrentContextPredictable())
+ currentContext = this;
return true;
}
+void GraphicsContextGLOpenGL::clearCurrentContext()
+{
+ EGLBoolean result = EGL_MakeCurrent(m_displayObj, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ ASSERT_UNUSED(result, result);
+ currentContext = nullptr;
+}
+
#if PLATFORM(IOS_FAMILY)
bool GraphicsContextGLOpenGL::releaseCurrentContext(ReleaseBehavior releaseBehavior)
{
// At the moment this function is relevant only when web thread lock owns the GraphicsContextGLOpenGL current context.
- ASSERT(!WebCore::isInWebProcess());
+ ASSERT(!isCurrentContextPredictable());
if (!EGL_BindAPI(EGL_OPENGL_ES_API))
return false;
@@ -476,9 +497,7 @@
LOG(WebGL, "Pretending the GPU has reset (%p). Lose the context.", this);
m_failNextStatusCheck = false;
forceContextLost();
-
- EGL_BindAPI(EGL_OPENGL_ES_API);
- EGL_MakeCurrent(m_displayObj, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ clearCurrentContext();
return;
}
Modified: trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGL.h (275096 => 275097)
--- trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGL.h 2021-03-26 15:34:24 UTC (rev 275096)
+++ trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGL.h 2021-03-26 15:34:49 UTC (rev 275097)
@@ -536,6 +536,7 @@
// Called once by all the public entry points that eventually call OpenGL.
// Called once by all the public entry points of ExtensionsGL that eventually call OpenGL.
bool makeContextCurrent() WARN_UNUSED_RETURN;
+ void clearCurrentContext();
// Take into account the user's requested context creation attributes,
// in particular stencil and antialias, and determine which could or