Diff
Modified: trunk/LayoutTests/ChangeLog (291748 => 291749)
--- trunk/LayoutTests/ChangeLog 2022-03-23 17:05:16 UTC (rev 291748)
+++ trunk/LayoutTests/ChangeLog 2022-03-23 17:12:07 UTC (rev 291749)
@@ -1,5 +1,16 @@
2022-03-23 Kimmo Kinnunen <kkinnu...@apple.com>
+ After losing context due to too many contexts, getError() does not return CONTEXT_LOST_WEBGL
+ https://bugs.webkit.org/show_bug.cgi?id=236965
+
+ Reviewed by Kenneth Russell.
+
+ * fast/canvas/webgl/lose-context-on-status-failure-expected.txt:
+ * webgl/lose-context-after-context-lost-expected.txt:
+ * webgl/max-active-contexts-webglcontextlost-prevent-default-expected.txt:
+
+2022-03-23 Kimmo Kinnunen <kkinnu...@apple.com>
+
Context2D drawImage(img, x, y, w, h) should not throw IndexSizeError when width == 0 or height == 0
https://bugs.webkit.org/show_bug.cgi?id=238195
Modified: trunk/LayoutTests/fast/canvas/webgl/lose-context-on-status-failure-expected.txt (291748 => 291749)
--- trunk/LayoutTests/fast/canvas/webgl/lose-context-on-status-failure-expected.txt 2022-03-23 17:05:16 UTC (rev 291748)
+++ trunk/LayoutTests/fast/canvas/webgl/lose-context-on-status-failure-expected.txt 2022-03-23 17:12:07 UTC (rev 291749)
@@ -1,7 +1,7 @@
-CONSOLE MESSAGE: WebGL: CONTEXT_LOST_WEBGL: loseContext: context lost
-CONSOLE MESSAGE: WebGL: CONTEXT_LOST_WEBGL: loseContext: context lost
-CONSOLE MESSAGE: WebGL: CONTEXT_LOST_WEBGL: loseContext: context lost
-CONSOLE MESSAGE: WebGL: CONTEXT_LOST_WEBGL: loseContext: context lost
+CONSOLE MESSAGE: WebGL: context lost.
+CONSOLE MESSAGE: WebGL: context lost.
+CONSOLE MESSAGE: WebGL: context lost.
+CONSOLE MESSAGE: WebGL: context lost.
Checks that a GPU status check failure will lose the context.
NOTE: This only passes in the test harness because it requires Internals.
Modified: trunk/LayoutTests/webgl/lose-context-after-context-lost-expected.txt (291748 => 291749)
--- trunk/LayoutTests/webgl/lose-context-after-context-lost-expected.txt 2022-03-23 17:05:16 UTC (rev 291748)
+++ trunk/LayoutTests/webgl/lose-context-after-context-lost-expected.txt 2022-03-23 17:12:07 UTC (rev 291749)
@@ -2,7 +2,7 @@
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-TEST COMPLETE: 29 PASS, 2 FAIL
+TEST COMPLETE: 31 PASS, 0 FAIL
Running test: loseMethod: loseContext, testedMethod: loseContext
PASS Got webglcontextlost.
@@ -19,13 +19,13 @@
Running test: loseMethod: manyContexts, testedMethod: loseContext
PASS Got webglcontextlost.
PASS gl.isContextLost() is true
-FAIL gl.getError() should be 37442. Was 0.
+PASS gl.getError() is gl.CONTEXT_LOST_WEBGL
PASS gl.getError() is gl.NO_ERROR
PASS Did not crash on tested method loseContext.
Running test: loseMethod: manyContexts, testedMethod: restoreContext
PASS Got webglcontextlost.
PASS gl.isContextLost() is true
-FAIL gl.getError() should be 37442. Was 0.
+PASS gl.getError() is gl.CONTEXT_LOST_WEBGL
PASS gl.getError() is gl.NO_ERROR
PASS Did not crash on tested method restoreContext.
Running test: loseMethod: gpuStatusFailure, testedMethod: loseContext
Modified: trunk/LayoutTests/webgl/max-active-contexts-webglcontextlost-prevent-default-expected.txt (291748 => 291749)
--- trunk/LayoutTests/webgl/max-active-contexts-webglcontextlost-prevent-default-expected.txt 2022-03-23 17:05:16 UTC (rev 291748)
+++ trunk/LayoutTests/webgl/max-active-contexts-webglcontextlost-prevent-default-expected.txt 2022-03-23 17:12:07 UTC (rev 291749)
@@ -2,7 +2,7 @@
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-TEST COMPLETE: 42 PASS, 10 FAIL
+TEST COMPLETE: 46 PASS, 6 FAIL
Running test: loseMethod: loseContext, loseMethod2: loseContext
PASS Got webglcontextlost and restore was attempted.
@@ -14,7 +14,7 @@
PASS Got webglcontextlost and restore was attempted.
PASS getError was expected value: CONTEXT_LOST_WEBGL :
PASS gl.isContextLost() is true
-PASS getError was expected value: NO_ERROR :
+FAIL getError expected: NO_ERROR. Was INVALID_OPERATION :
Running test: loseMethod: loseContext, loseMethod2: gpuStatusFailure
PASS Got webglcontextlost and restore was attempted.
PASS getError was expected value: CONTEXT_LOST_WEBGL :
@@ -27,23 +27,23 @@
PASS getError was expected value: NO_ERROR :
Running test: loseMethod: manyContexts, loseMethod2: loseContext
PASS Got webglcontextlost and restore was attempted.
-FAIL getError expected: CONTEXT_LOST_WEBGL. Was NO_ERROR :
-FAIL getError expected: INVALID_OPERATION. Was NO_ERROR :
+PASS getError was expected value: CONTEXT_LOST_WEBGL :
+PASS getError was expected value: INVALID_OPERATION :
PASS gl.isContextLost() is true
PASS getError was expected value: NO_ERROR :
Running test: loseMethod: manyContexts, loseMethod2: manyContexts
PASS Got webglcontextlost and restore was attempted.
-FAIL getError expected: CONTEXT_LOST_WEBGL. Was NO_ERROR :
+PASS getError was expected value: CONTEXT_LOST_WEBGL :
PASS gl.isContextLost() is true
PASS getError was expected value: NO_ERROR :
Running test: loseMethod: manyContexts, loseMethod2: gpuStatusFailure
PASS Got webglcontextlost and restore was attempted.
-FAIL getError expected: CONTEXT_LOST_WEBGL. Was NO_ERROR :
+PASS getError was expected value: CONTEXT_LOST_WEBGL :
PASS gl.isContextLost() is true
PASS getError was expected value: NO_ERROR :
Running test: loseMethod: manyContexts, loseMethod2: nothing
PASS Got webglcontextlost and restore was attempted.
-FAIL getError expected: CONTEXT_LOST_WEBGL. Was NO_ERROR :
+PASS getError was expected value: CONTEXT_LOST_WEBGL :
PASS gl.isContextLost() is true
PASS getError was expected value: NO_ERROR :
Running test: loseMethod: gpuStatusFailure, loseMethod2: loseContext
Modified: trunk/Source/WebCore/ChangeLog (291748 => 291749)
--- trunk/Source/WebCore/ChangeLog 2022-03-23 17:05:16 UTC (rev 291748)
+++ trunk/Source/WebCore/ChangeLog 2022-03-23 17:12:07 UTC (rev 291749)
@@ -1,5 +1,53 @@
2022-03-23 Kimmo Kinnunen <kkinnu...@apple.com>
+ After losing context due to too many contexts, getError() does not return CONTEXT_LOST_WEBGL
+ https://bugs.webkit.org/show_bug.cgi?id=236965
+
+ Reviewed by Kenneth Russell.
+
+ After generating context lost, getError() is specified to return:
+ - CONTEXT_LOST_WEBGL for first call
+ - NO_ERROR for all the next calls.
+
+ WEBGL_lose_context is specified to add INVALID_OPERATION errors
+ even after context lost.
+
+ Change the code so that CONTEXT_LOST_WEBGL and WEBGL_lose_context induced
+ INVALID_OPERATION errors go to error vector in context lost -specific state.
+
+ Previously, these errors went into the m_context error vector. This is problematic
+ especially in the case where context loss happens where the m_context gets destroyed --
+ the error vector would be gone. This kind of loss happens for example when contexts
+ get lost due to the process having too many active contexts (least active context is "recycled").
+
+ Previously, any synthetized error was potentially obtainable after context lost. This is problematic
+ as it is not as specified. As mentioned above, only errors allowed after context lost is
+ - CONTEXT_LOST_WEBGL first after context lost
+ - WEBGL_lose_context.loseContext() and WEBGL_lose_context.restoreContext() induced INVALID_OPERATIONs
+
+ Changes the behavior to not report INVALID_OPERATION error in the theoretical case where we fail to
+ instantiate a new context. This is not allowed by the spec. Instead, just print an error to the console.
+
+ No new tests, updates the expectations of old ones with less failures.
+
+ * html/canvas/WebGLRenderingContextBase.cpp:
+ (WebCore::WebGLRenderingContextBase::initializeNewContext):
+ (WebCore::WebGLRenderingContextBase::getError):
+ (WebCore::WebGLRenderingContextBase::isContextLost const):
+ (WebCore::WebGLRenderingContextBase::isContextLostOrPending):
+ (WebCore::WebGLRenderingContextBase::forceLostContext):
+ (WebCore::WebGLRenderingContextBase::loseContextImpl):
+ (WebCore::WebGLRenderingContextBase::forceRestoreContext):
+ (WebCore::WebGLRenderingContextBase::isContextUnrecoverablyLost const):
+ (WebCore::WebGLRenderingContextBase::scheduleTaskToDispatchContextLostEvent):
+ (WebCore::WebGLRenderingContextBase::maybeRestoreContext):
+ (WebCore::WebGLRenderingContextBase::synthesizeGLError):
+ (WebCore::WebGLRenderingContextBase::synthesizeLostContextGLError):
+ * html/canvas/WebGLRenderingContextBase.h:
+ (WebCore::WebGLRenderingContextBase::ContextLostState::ContextLostState):
+
+2022-03-23 Kimmo Kinnunen <kkinnu...@apple.com>
+
Context2D drawImage(img, x, y, w, h) should not throw IndexSizeError when width == 0 or height == 0
https://bugs.webkit.org/show_bug.cgi?id=238195
Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp (291748 => 291749)
--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp 2022-03-23 17:05:16 UTC (rev 291748)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp 2022-03-23 17:12:07 UTC (rev 291749)
@@ -1046,7 +1046,7 @@
void WebGLRenderingContextBase::initializeNewContext()
{
- ASSERT(!m_contextLost);
+ ASSERT(!isContextLost());
m_needsUpdate = true;
m_markedCanvasDirty = false;
m_activeTextureUnit = 0;
@@ -3166,8 +3166,14 @@
GCGLenum WebGLRenderingContextBase::getError()
{
- if (!m_context || m_isPendingPolicyResolution)
+ if (isContextLost()) {
+ auto& errors = m_contextLostState->errors;
+ if (!errors.isEmpty())
+ return errors.takeFirst();
return GraphicsContextGL::NO_ERROR;
+ }
+ if (m_isPendingPolicyResolution)
+ return GraphicsContextGL::NO_ERROR;
return m_context->getError();
}
@@ -4055,7 +4061,7 @@
bool WebGLRenderingContextBase::isContextLost() const
{
- return m_contextLost;
+ return m_contextLostState.has_value();
}
bool WebGLRenderingContextBase::isContextLostOrPending()
@@ -4076,7 +4082,7 @@
m_hasRequestedPolicyResolution = true;
}
- return m_contextLost || m_isPendingPolicyResolution;
+ return isContextLost() || m_isPendingPolicyResolution;
}
GCGLboolean WebGLRenderingContextBase::isEnabled(GCGLenum cap)
@@ -6433,7 +6439,7 @@
void WebGLRenderingContextBase::forceLostContext(WebGLRenderingContextBase::LostContextMode mode)
{
if (isContextLostOrPending()) {
- synthesizeGLError(GraphicsContextGL::INVALID_OPERATION, "loseContext", "context already lost");
+ synthesizeLostContextGLError(GraphicsContextGL::INVALID_OPERATION, "loseContext", "context already lost");
return;
}
@@ -6444,9 +6450,11 @@
{
if (isContextLost())
return;
+ if (mode == RealLostContext)
+ printToConsole(MessageLevel::Error, "WebGL: context lost.");
- m_contextLost = true;
- m_contextLostMode = mode;
+ m_contextLostState = ContextLostState { mode };
+ m_contextLostState->errors.add(GraphicsContextGL::CONTEXT_LOST_WEBGL);
detachAndRemoveAllObjects();
loseExtensions(mode);
@@ -6459,13 +6467,7 @@
if (m_context->getError() == GraphicsContextGL::NO_ERROR)
break;
}
- ConsoleDisplayPreference display = (mode == RealLostContext) ? DisplayInConsole: DontDisplayInConsole;
- synthesizeGLError(GraphicsContextGL::CONTEXT_LOST_WEBGL, "loseContext", "context lost", display);
- // Don't allow restoration unless the context lost event has both been
- // dispatched and its default behavior prevented.
- m_restoreAllowed = false;
-
// Always defer the dispatch of the context lost event, to implement
// the spec behavior of queueing a task.
scheduleTaskToDispatchContextLostEvent();
@@ -6477,10 +6479,9 @@
synthesizeGLError(GraphicsContextGL::INVALID_OPERATION, "restoreContext", "context not lost");
return;
}
-
- if (!m_restoreAllowed) {
- if (m_contextLostMode == SyntheticLostContext)
- synthesizeGLError(GraphicsContextGL::INVALID_OPERATION, "restoreContext", "context restoration not allowed");
+ if (!m_contextLostState->restoreRequested) {
+ if (m_contextLostState->mode == SyntheticLostContext)
+ synthesizeLostContextGLError(GraphicsContextGL::INVALID_OPERATION, "restoreContext", "context restoration not allowed");
return;
}
@@ -6490,7 +6491,7 @@
bool WebGLRenderingContextBase::isContextUnrecoverablyLost() const
{
- return m_contextLost && !m_restoreAllowed;
+ return isContextLost() && !m_contextLostState->restoreRequested;
}
RefPtr<GraphicsLayerContentsDisplayDelegate> WebGLRenderingContextBase::layerContentsDisplayDelegate()
@@ -7732,11 +7733,12 @@
queueTaskKeepingObjectAlive(*canvas, TaskSource::WebGL, [this, canvas] {
if (isContextStopped())
return;
-
+ if (!isContextLost())
+ return;
auto event = WebGLContextEvent::create(eventNames().webglcontextlostEvent, Event::CanBubble::No, Event::IsCancelable::Yes, emptyString());
canvas->dispatchEvent(event);
- m_restoreAllowed = event->defaultPrevented();
- if (m_contextLostMode == RealLostContext && m_restoreAllowed)
+ m_contextLostState->restoreRequested = event->defaultPrevented();
+ if (m_contextLostState->mode == RealLostContext && m_contextLostState->restoreRequested)
m_restoreTimer.startOneShot(0_s);
});
}
@@ -7744,19 +7746,11 @@
void WebGLRenderingContextBase::maybeRestoreContext()
{
RELEASE_ASSERT(!m_isSuspended);
- ASSERT(m_contextLost);
- if (!m_contextLost)
+ if (!isContextLost() || !m_contextLostState->restoreRequested) {
+ ASSERT_NOT_REACHED();
return;
+ }
- // The rendering context is not restored unless the default behavior of the
- // webglcontextlost event was prevented earlier.
- //
- // Because of the way m_restoreTimer is set up for real vs. synthetic lost
- // context events, we don't have to worry about this test short-circuiting
- // the retry loop for real context lost events.
- if (!m_restoreAllowed)
- return;
-
auto* canvas = htmlCanvas();
if (!canvas)
return;
@@ -7780,17 +7774,16 @@
RefPtr<GraphicsContextGL> context = hostWindow->createGraphicsContextGL(m_attributes);
if (!context) {
- if (m_contextLostMode == RealLostContext)
+ if (m_contextLostState->mode == RealLostContext)
m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts);
else
- // This likely shouldn't happen but is the best way to report it to the WebGL app.
- synthesizeGLError(GraphicsContextGL::INVALID_OPERATION, "", "error restoring context");
+ printToConsole(MessageLevel::Error, "WebGL: error restoring lost context.");
return;
}
setGraphicsContextGL(context.releaseNonNull());
addActivityStateChangeObserverIfNecessary();
- m_contextLost = false;
+ m_contextLostState = std::nullopt;
setupFlags();
initializeNewContext();
canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextrestoredEvent, Event::CanBubble::No, Event::IsCancelable::Yes, emptyString()));
@@ -7872,16 +7865,19 @@
} // namespace anonymous
-void WebGLRenderingContextBase::synthesizeGLError(GCGLenum error, const char* functionName, const char* description, ConsoleDisplayPreference display)
+void WebGLRenderingContextBase::synthesizeGLError(GCGLenum error, const char* functionName, const char* description)
{
- if (m_synthesizedErrorsToConsole && display == DisplayInConsole) {
- String str = "WebGL: " + GetErrorString(error) + ": " + String(functionName) + ": " + String(description);
- printToConsole(MessageLevel::Error, str);
- }
+ printToConsole(MessageLevel::Error, makeString("WebGL: ", GetErrorString(error), ": ", functionName, ": ", description));
if (m_context)
m_context->synthesizeGLError(error);
}
+void WebGLRenderingContextBase::synthesizeLostContextGLError(GCGLenum error, const char* functionName, const char* description)
+{
+ printToConsole(MessageLevel::Error, makeString("WebGL: ", GetErrorString(error), ": ", functionName, ": ", description));
+ m_contextLostState->errors.add(error);
+}
+
void WebGLRenderingContextBase::applyStencilTest()
{
bool haveStencilBuffer = false;
Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h (291748 => 291749)
--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h 2022-03-23 17:05:16 UTC (rev 291748)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h 2022-03-23 17:12:07 UTC (rev 291749)
@@ -48,6 +48,7 @@
#include <limits>
#include <memory>
#include <wtf/CheckedArithmetic.h>
+#include <wtf/ListHashSet.h>
#include <wtf/Lock.h>
#if ENABLE(WEBGL2)
@@ -548,11 +549,20 @@
void prepareForDisplay() final;
void updateActiveOrdinal();
+ struct ContextLostState {
+ ContextLostState(LostContextMode mode)
+ : mode(mode)
+ {
+ }
+ ListHashSet<GCGLint> errors; // Losing context and WEBGL_lose_context generates errors here.
+ LostContextMode mode { LostContextMode::RealLostContext };
+ bool restoreRequested { false };
+ };
+
RefPtr<GraphicsContextGL> m_context;
RefPtr<WebGLContextGroup> m_contextGroup;
Lock m_objectGraphLock;
- bool m_restoreAllowed { false };
SuspendableTimer m_restoreTimer;
bool m_needsUpdate;
@@ -652,8 +662,7 @@
bool m_unpackPremultiplyAlpha;
GCGLenum m_unpackColorspaceConversion;
- bool m_contextLost { false };
- LostContextMode m_contextLostMode { SyntheticLostContext };
+ std::optional<ContextLostState> m_contextLostState;
WebGLContextAttributes m_attributes;
bool m_layerCleared;
@@ -1095,8 +1104,8 @@
#endif
// Wrapper for GraphicsContextGLOpenGL::synthesizeGLError that sends a message to the _javascript_ console.
- enum ConsoleDisplayPreference { DisplayInConsole, DontDisplayInConsole };
- void synthesizeGLError(GCGLenum, const char* functionName, const char* description, ConsoleDisplayPreference = DisplayInConsole);
+ void synthesizeGLError(GCGLenum, const char* functionName, const char* description);
+ void synthesizeLostContextGLError(GCGLenum, const char* functionName, const char* description);
String ensureNotNull(const String&) const;
Modified: trunk/Source/WebKit/ChangeLog (291748 => 291749)
--- trunk/Source/WebKit/ChangeLog 2022-03-23 17:05:16 UTC (rev 291748)
+++ trunk/Source/WebKit/ChangeLog 2022-03-23 17:12:07 UTC (rev 291749)
@@ -1,3 +1,18 @@
+2022-03-23 Kimmo Kinnunen <kkinnu...@apple.com>
+
+ After losing context due to too many contexts, getError() does not return CONTEXT_LOST_WEBGL
+ https://bugs.webkit.org/show_bug.cgi?id=236965
+
+ Reviewed by Kenneth Russell.
+
+ Remove recording of synthetic webgl context lost error from the proxy.
+ This is now recorded in the WebGLRenderingContextBase.
+
+ * WebProcess/GPU/graphics/RemoteGraphicsContextGLProxy.cpp:
+ (WebKit::RemoteGraphicsContextGLProxy::synthesizeGLError):
+ (WebKit::RemoteGraphicsContextGLProxy::getError):
+ * WebProcess/GPU/graphics/RemoteGraphicsContextGLProxy.h:
+
2022-03-23 Fujii Hironori <hironori.fu...@sony.com>
[WinCairo] Unreviewed build fix after r291733
Modified: trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteGraphicsContextGLProxy.cpp (291748 => 291749)
--- trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteGraphicsContextGLProxy.cpp 2022-03-23 17:05:16 UTC (rev 291748)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteGraphicsContextGLProxy.cpp 2022-03-23 17:12:07 UTC (rev 291749)
@@ -215,7 +215,6 @@
markContextLost();
return;
}
- m_errorWhenContextIsLost = error;
}
GCGLenum RemoteGraphicsContextGLProxy::getError()
@@ -227,7 +226,7 @@
markContextLost();
return static_cast<GCGLenum>(returnValue);
}
- return std::exchange(m_errorWhenContextIsLost, NO_ERROR);
+ return NO_ERROR;
}
void RemoteGraphicsContextGLProxy::simulateEventForTesting(SimulatedEventForTesting event)
Modified: trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteGraphicsContextGLProxy.h (291748 => 291749)
--- trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteGraphicsContextGLProxy.h 2022-03-23 17:05:16 UTC (rev 291748)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteGraphicsContextGLProxy.h 2022-03-23 17:12:07 UTC (rev 291749)
@@ -366,7 +366,6 @@
HashSet<String> m_requestableExtensions;
HashSet<String> m_enabledExtensions;
- GCGLenum m_errorWhenContextIsLost = NO_ERROR;
IPC::StreamClientConnection m_streamConnection;
};