Title: [259130] trunk/Source/WebCore
Revision
259130
Author
[email protected]
Date
2020-03-27 11:30:08 -0700 (Fri, 27 Mar 2020)

Log Message

[StressGC] ASSERTION FAILED: m_wrapper under WebCore::WebGLRenderingContextBase::dispatchContextLostEvent
https://bugs.webkit.org/show_bug.cgi?id=209660
<rdar://problem/60541733>

Reviewed by Darin Adler.

Make HTMLCanvasElement an ActiveDOMObject since WebGLRenderingContextBase needs to dispatch events
asynchronously on its canvas element. Update WebGLRenderingContextBase to use the HTML event loop
to dispatch those events asynchronously instead of using suspendible timers.

No new tests, already covered by webgl/max-active-contexts-webglcontextlost-prevent-default.html.

* dom/TaskSource.h:
* html/HTMLCanvasElement.cpp:
(WebCore::HTMLCanvasElement::HTMLCanvasElement):
(WebCore::HTMLCanvasElement::create):
(WebCore::HTMLCanvasElement::activeDOMObjectName const):
* html/HTMLCanvasElement.h:
* html/HTMLCanvasElement.idl:
* html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::WebGLRenderingContextBase::WebGLRenderingContextBase):
(WebCore::WebGLRenderingContextBase::loseContextImpl):
(WebCore::WebGLRenderingContextBase::scheduleTaskToDispatchContextLostEvent):
(WebCore::WebGLRenderingContextBase::dispatchContextChangedNotification):
(WebCore::WebGLRenderingContextBase::dispatchContextLostEvent): Deleted.
(WebCore::WebGLRenderingContextBase::dispatchContextChangedEvent): Deleted.
* html/canvas/WebGLRenderingContextBase.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (259129 => 259130)


--- trunk/Source/WebCore/ChangeLog	2020-03-27 18:21:40 UTC (rev 259129)
+++ trunk/Source/WebCore/ChangeLog	2020-03-27 18:30:08 UTC (rev 259130)
@@ -1,3 +1,33 @@
+2020-03-27  Chris Dumez  <[email protected]>
+
+        [StressGC] ASSERTION FAILED: m_wrapper under WebCore::WebGLRenderingContextBase::dispatchContextLostEvent
+        https://bugs.webkit.org/show_bug.cgi?id=209660
+        <rdar://problem/60541733>
+
+        Reviewed by Darin Adler.
+
+        Make HTMLCanvasElement an ActiveDOMObject since WebGLRenderingContextBase needs to dispatch events
+        asynchronously on its canvas element. Update WebGLRenderingContextBase to use the HTML event loop
+        to dispatch those events asynchronously instead of using suspendible timers.
+
+        No new tests, already covered by webgl/max-active-contexts-webglcontextlost-prevent-default.html.
+
+        * dom/TaskSource.h:
+        * html/HTMLCanvasElement.cpp:
+        (WebCore::HTMLCanvasElement::HTMLCanvasElement):
+        (WebCore::HTMLCanvasElement::create):
+        (WebCore::HTMLCanvasElement::activeDOMObjectName const):
+        * html/HTMLCanvasElement.h:
+        * html/HTMLCanvasElement.idl:
+        * html/canvas/WebGLRenderingContextBase.cpp:
+        (WebCore::WebGLRenderingContextBase::WebGLRenderingContextBase):
+        (WebCore::WebGLRenderingContextBase::loseContextImpl):
+        (WebCore::WebGLRenderingContextBase::scheduleTaskToDispatchContextLostEvent):
+        (WebCore::WebGLRenderingContextBase::dispatchContextChangedNotification):
+        (WebCore::WebGLRenderingContextBase::dispatchContextLostEvent): Deleted.
+        (WebCore::WebGLRenderingContextBase::dispatchContextChangedEvent): Deleted.
+        * html/canvas/WebGLRenderingContextBase.h:
+
 2020-03-27  Simon Fraser  <[email protected]>
 
         Use Optional<> for a lazily-computed bounds rectangle

Modified: trunk/Source/WebCore/dom/TaskSource.h (259129 => 259130)


--- trunk/Source/WebCore/dom/TaskSource.h	2020-03-27 18:21:40 UTC (rev 259129)
+++ trunk/Source/WebCore/dom/TaskSource.h	2020-03-27 18:30:08 UTC (rev 259130)
@@ -38,6 +38,7 @@
     Networking,
     PostedMessageQueue,
     UserInteraction,
+    WebGL,
 
     // Internal to WebCore
     InternalAsyncTask, // Safe to re-order or delay.

Modified: trunk/Source/WebCore/html/HTMLCanvasElement.cpp (259129 => 259130)


--- trunk/Source/WebCore/html/HTMLCanvasElement.cpp	2020-03-27 18:21:40 UTC (rev 259129)
+++ trunk/Source/WebCore/html/HTMLCanvasElement.cpp	2020-03-27 18:30:08 UTC (rev 259130)
@@ -113,6 +113,7 @@
 HTMLCanvasElement::HTMLCanvasElement(const QualifiedName& tagName, Document& document)
     : HTMLElement(tagName, document)
     , CanvasBase(IntSize(defaultWidth, defaultHeight))
+    , ActiveDOMObject(document)
 {
     ASSERT(hasTagName(canvasTag));
 }
@@ -119,12 +120,16 @@
 
 Ref<HTMLCanvasElement> HTMLCanvasElement::create(Document& document)
 {
-    return adoptRef(*new HTMLCanvasElement(canvasTag, document));
+    auto canvas = adoptRef(*new HTMLCanvasElement(canvasTag, document));
+    canvas->suspendIfNeeded();
+    return canvas;
 }
 
 Ref<HTMLCanvasElement> HTMLCanvasElement::create(const QualifiedName& tagName, Document& document)
 {
-    return adoptRef(*new HTMLCanvasElement(tagName, document));
+    auto canvas = adoptRef(*new HTMLCanvasElement(tagName, document));
+    canvas->suspendIfNeeded();
+    return canvas;
 }
 
 HTMLCanvasElement::~HTMLCanvasElement()
@@ -945,4 +950,9 @@
     m_didClearImageBuffer = false;
 }
 
+const char* HTMLCanvasElement::activeDOMObjectName() const
+{
+    return "HTMLCanvasElement";
 }
+
+}

Modified: trunk/Source/WebCore/html/HTMLCanvasElement.h (259129 => 259130)


--- trunk/Source/WebCore/html/HTMLCanvasElement.h	2020-03-27 18:21:40 UTC (rev 259129)
+++ trunk/Source/WebCore/html/HTMLCanvasElement.h	2020-03-27 18:30:08 UTC (rev 259130)
@@ -27,6 +27,7 @@
 
 #pragma once
 
+#include "ActiveDOMObject.h"
 #include "CanvasBase.h"
 #include "FloatRect.h"
 #include "HTMLElement.h"
@@ -57,7 +58,7 @@
 using AsTextFlags = unsigned;
 }
 
-class HTMLCanvasElement final : public HTMLElement, public CanvasBase {
+class HTMLCanvasElement final : public HTMLElement, public CanvasBase, public ActiveDOMObject {
     WTF_MAKE_ISO_ALLOCATED(HTMLCanvasElement);
 public:
     static Ref<HTMLCanvasElement> create(Document&);
@@ -132,6 +133,7 @@
     HTMLCanvasElement(const QualifiedName&, Document&);
 
     bool isHTMLCanvasElement() const final { return true; }
+    const char* activeDOMObjectName() const final;
 
     void parseAttribute(const QualifiedName&, const AtomString&) final;
     RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final;

Modified: trunk/Source/WebCore/html/HTMLCanvasElement.idl (259129 => 259130)


--- trunk/Source/WebCore/html/HTMLCanvasElement.idl	2020-03-27 18:21:40 UTC (rev 259129)
+++ trunk/Source/WebCore/html/HTMLCanvasElement.idl	2020-03-27 18:30:08 UTC (rev 259130)
@@ -38,6 +38,7 @@
     CanvasRenderingContext2D) RenderingContext;
 
 [
+    ActiveDOMObject,
     JSGenerateToNativeObject,
     ReportExtraMemoryCost,
     ReportExternalMemoryCost,

Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp (259129 => 259130)


--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp	2020-03-27 18:21:40 UTC (rev 259129)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp	2020-03-27 18:30:08 UTC (rev 259130)
@@ -611,8 +611,6 @@
 
 WebGLRenderingContextBase::WebGLRenderingContextBase(CanvasBase& canvas, WebGLContextAttributes attributes)
     : GPUBasedCanvasRenderingContext(canvas)
-    , m_dispatchContextLostEventTimer(canvas.scriptExecutionContext(), *this, &WebGLRenderingContextBase::dispatchContextLostEvent)
-    , m_dispatchContextChangedEventTimer(canvas.scriptExecutionContext(), *this, &WebGLRenderingContextBase::dispatchContextChangedEvent)
     , m_restoreTimer(canvas.scriptExecutionContext(), *this, &WebGLRenderingContextBase::maybeRestoreContext)
     , m_attributes(attributes)
     , m_numGLErrorsToConsoleAllowed(maxGLErrorsAllowedToConsole)
@@ -619,8 +617,6 @@
     , m_isPendingPolicyResolution(true)
     , m_checkForContextLossHandlingTimer(*this, &WebGLRenderingContextBase::checkForContextLossHandling)
 {
-    m_dispatchContextLostEventTimer.suspendIfNeeded();
-    m_dispatchContextChangedEventTimer.suspendIfNeeded();
     m_restoreTimer.suspendIfNeeded();
 
     registerWithWebGLStateTracker();
@@ -630,8 +626,6 @@
 WebGLRenderingContextBase::WebGLRenderingContextBase(CanvasBase& canvas, Ref<GraphicsContextGLOpenGL>&& context, WebGLContextAttributes attributes)
     : GPUBasedCanvasRenderingContext(canvas)
     , m_context(WTFMove(context))
-    , m_dispatchContextLostEventTimer(canvas.scriptExecutionContext(), *this, &WebGLRenderingContextBase::dispatchContextLostEvent)
-    , m_dispatchContextChangedEventTimer(canvas.scriptExecutionContext(), *this, &WebGLRenderingContextBase::dispatchContextChangedEvent)
     , m_restoreTimer(canvas.scriptExecutionContext(), *this, &WebGLRenderingContextBase::maybeRestoreContext)
     , m_generatedImageCache(4)
     , m_attributes(attributes)
@@ -638,8 +632,6 @@
     , m_numGLErrorsToConsoleAllowed(maxGLErrorsAllowedToConsole)
     , m_checkForContextLossHandlingTimer(*this, &WebGLRenderingContextBase::checkForContextLossHandling)
 {
-    m_dispatchContextLostEventTimer.suspendIfNeeded();
-    m_dispatchContextChangedEventTimer.suspendIfNeeded();
     m_restoreTimer.suspendIfNeeded();
 
     m_contextGroup = WebGLContextGroup::create();
@@ -5195,7 +5187,7 @@
 
     // Always defer the dispatch of the context lost event, to implement
     // the spec behavior of queueing a task.
-    m_dispatchContextLostEventTimer.startOneShot(0_s);
+    scheduleTaskToDispatchContextLostEvent();
 }
 
 void WebGLRenderingContextBase::forceRestoreContext()
@@ -6318,18 +6310,20 @@
 }
 #endif
 
-void WebGLRenderingContextBase::dispatchContextLostEvent()
+void WebGLRenderingContextBase::scheduleTaskToDispatchContextLostEvent()
 {
-    RELEASE_ASSERT(!m_isSuspended);
     auto* canvas = htmlCanvas();
     if (!canvas)
         return;
 
-    Ref<WebGLContextEvent> 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_restoreTimer.startOneShot(0_s);
+    // It is safe to capture |this| because we keep the canvas element alive and it owns |this|.
+    queueTaskKeepingObjectAlive(*canvas, TaskSource::WebGL, [this, canvas] {
+        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_restoreTimer.startOneShot(0_s);
+    });
 }
 
 void WebGLRenderingContextBase::maybeRestoreContext()
@@ -6726,18 +6720,11 @@
 
 void WebGLRenderingContextBase::dispatchContextChangedNotification()
 {
-    if (!m_dispatchContextChangedEventTimer.isActive())
-        m_dispatchContextChangedEventTimer.startOneShot(0_s);
-}
-
-void WebGLRenderingContextBase::dispatchContextChangedEvent()
-{
-    RELEASE_ASSERT(!m_isSuspended);
     auto* canvas = htmlCanvas();
     if (!canvas)
         return;
 
-    canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextchangedEvent, Event::CanBubble::No, Event::IsCancelable::Yes, emptyString()));
+    queueTaskToDispatchEvent(*canvas, TaskSource::WebGL, WebGLContextEvent::create(eventNames().webglcontextchangedEvent, Event::CanBubble::No, Event::IsCancelable::Yes, emptyString()));
 }
 
 

Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h (259129 => 259130)


--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h	2020-03-27 18:21:40 UTC (rev 259129)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h	2020-03-27 18:30:08 UTC (rev 259130)
@@ -462,13 +462,6 @@
     RefPtr<GraphicsContextGLOpenGL> m_context;
     RefPtr<WebGLContextGroup> m_contextGroup;
 
-    // Dispatches a context lost event once it is determined that one is needed.
-    // This is used both for synthetic and real context losses. For real ones, it's
-    // likely that there's no _javascript_ on the stack, but that might be dependent
-    // on how exactly the platform discovers that the context was lost. For better
-    // portability we always defer the dispatch of the event.
-    SuspendableTimer m_dispatchContextLostEventTimer;
-    SuspendableTimer m_dispatchContextChangedEventTimer;
     bool m_restoreAllowed { false };
     SuspendableTimer m_restoreTimer;
 
@@ -864,8 +857,7 @@
     template <typename T> unsigned getMaxIndex(const RefPtr<JSC::ArrayBuffer> elementArrayBuffer, GCGLintptr uoffset, GCGLsizei n);
 
 private:
-    void dispatchContextLostEvent();
-    void dispatchContextChangedEvent();
+    void scheduleTaskToDispatchContextLostEvent();
     // Helper for restoration after context lost.
     void maybeRestoreContext();
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to