Title: [181625] trunk/Source
Revision
181625
Author
[email protected]
Date
2015-03-17 01:41:19 -0700 (Tue, 17 Mar 2015)

Log Message

Web Inspector: Show rendering frames (and FPS) in Layout and Rendering timeline
https://bugs.webkit.org/show_bug.cgi?id=142029

Patch by Matt Baker <[email protected]> on 2015-03-17
Reviewed by Timothy Hatcher.

Source/_javascript_Core:

* inspector/protocol/Timeline.json:
Added new event type for runloop timeline records.

Source/WebCore:

Add new functionality to the Inspector timelines backend to add runloop data to timeline recordings.

* inspector/InspectorTimelineAgent.cpp:
(WebCore::currentRunLoop):
(WebCore::InspectorTimelineAgent::internalStart):
(WebCore::InspectorTimelineAgent::internalStop):
(WebCore::toProtocol):
(WebCore::InspectorTimelineAgent::InspectorTimelineAgent):
Install observers for the begining and end of the runloop when recording begins. All other
instrumented timeline events get added as children of the current runloop record, which is
sent to the frontend once the runloop completes.

* inspector/InspectorTimelineAgent.h:

* platform/cf/RunLoopObserver.cpp:
(WebCore::RunLoopObserver::schedule):
Wrapper changed to allow observing arbitrary runloop activities.

* platform/cf/RunLoopObserver.h:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (181624 => 181625)


--- trunk/Source/_javascript_Core/ChangeLog	2015-03-17 08:39:05 UTC (rev 181624)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-03-17 08:41:19 UTC (rev 181625)
@@ -1,3 +1,13 @@
+2015-03-17  Matt Baker  <[email protected]>
+
+        Web Inspector: Show rendering frames (and FPS) in Layout and Rendering timeline
+        https://bugs.webkit.org/show_bug.cgi?id=142029
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/protocol/Timeline.json:
+        Added new event type for runloop timeline records.
+
 2015-03-16  Ryosuke Niwa  <[email protected]>
 
         Enable ES6 classes by default

Modified: trunk/Source/_javascript_Core/inspector/protocol/Timeline.json (181624 => 181625)


--- trunk/Source/_javascript_Core/inspector/protocol/Timeline.json	2015-03-17 08:39:05 UTC (rev 181624)
+++ trunk/Source/_javascript_Core/inspector/protocol/Timeline.json	2015-03-17 08:41:19 UTC (rev 181625)
@@ -13,6 +13,7 @@
                 "InvalidateLayout",
                 "Layout",
                 "Paint",
+                "RunLoop",
                 "ScrollLayer",
                 "ParseHTML",
                 "TimerInstall",

Modified: trunk/Source/WebCore/ChangeLog (181624 => 181625)


--- trunk/Source/WebCore/ChangeLog	2015-03-17 08:39:05 UTC (rev 181624)
+++ trunk/Source/WebCore/ChangeLog	2015-03-17 08:41:19 UTC (rev 181625)
@@ -1,3 +1,30 @@
+2015-03-17  Matt Baker  <[email protected]>
+
+        Web Inspector: Show rendering frames (and FPS) in Layout and Rendering timeline
+        https://bugs.webkit.org/show_bug.cgi?id=142029
+
+        Reviewed by Timothy Hatcher.
+
+        Add new functionality to the Inspector timelines backend to add runloop data to timeline recordings.
+
+        * inspector/InspectorTimelineAgent.cpp:
+        (WebCore::currentRunLoop):
+        (WebCore::InspectorTimelineAgent::internalStart):
+        (WebCore::InspectorTimelineAgent::internalStop):
+        (WebCore::toProtocol):
+        (WebCore::InspectorTimelineAgent::InspectorTimelineAgent):
+        Install observers for the begining and end of the runloop when recording begins. All other
+        instrumented timeline events get added as children of the current runloop record, which is
+        sent to the frontend once the runloop completes.
+
+        * inspector/InspectorTimelineAgent.h:
+
+        * platform/cf/RunLoopObserver.cpp:
+        (WebCore::RunLoopObserver::schedule):
+        Wrapper changed to allow observing arbitrary runloop activities.
+
+        * platform/cf/RunLoopObserver.h:
+
 2015-03-17  Philippe Normand  <[email protected]>
 
         [GTK] basic OpenWebRTC build support

Modified: trunk/Source/WebCore/inspector/InspectorTimelineAgent.cpp (181624 => 181625)


--- trunk/Source/WebCore/inspector/InspectorTimelineAgent.cpp	2015-03-17 08:39:05 UTC (rev 181624)
+++ trunk/Source/WebCore/inspector/InspectorTimelineAgent.cpp	2015-03-17 08:41:19 UTC (rev 181625)
@@ -54,10 +54,37 @@
 #include <profiler/LegacyProfiler.h>
 #include <wtf/CurrentTime.h>
 
+#if PLATFORM(IOS)
+#include "RuntimeApplicationChecksIOS.h"
+#include <WebCore/WebCoreThread.h>
+#endif
+
+#if PLATFORM(COCOA)
+#include <WebCore/RunLoopObserver.h>
+#endif
+
 using namespace Inspector;
 
 namespace WebCore {
 
+#if PLATFORM(COCOA)
+static const CFIndex frameStopRunLoopOrder = (CFIndex)RunLoopObserver::WellKnownRunLoopOrders::CoreAnimationCommit + 1;
+
+static CFRunLoopRef currentRunLoop()
+{
+#if PLATFORM(IOS)
+    // A race condition during WebView deallocation can lead to a crash if the layer sync run loop
+    // observer is added to the main run loop <rdar://problem/9798550>. However, for responsiveness,
+    // we still allow this, see <rdar://problem/7403328>. Since the race condition and subsequent
+    // crash are especially troublesome for iBooks, we never allow the observer to be added to the
+    // main run loop in iBooks.
+    if (applicationIsIBooksOnIOS())
+        return WebThreadRunLoop();
+#endif
+    return CFRunLoopGetCurrent();
+}
+#endif
+
 InspectorTimelineAgent::~InspectorTimelineAgent()
 {
 }
@@ -122,6 +149,33 @@
 
     m_enabled = true;
 
+    // FIXME: Abstract away platform-specific code once https://bugs.webkit.org/show_bug.cgi?id=142748 is fixed.
+
+#if PLATFORM(COCOA)
+    m_frameStartObserver = RunLoopObserver::create(0, [this]() {
+        if (!m_enabled || m_didStartRecordingRunLoop)
+            return;
+
+        pushCurrentRecord(InspectorObject::create(), TimelineRecordType::RunLoop, false, nullptr);
+        m_didStartRecordingRunLoop = true;
+    });
+
+    m_frameStopObserver = RunLoopObserver::create(frameStopRunLoopOrder, [this]() {
+        if (!m_enabled || !m_didStartRecordingRunLoop)
+            return;
+
+        didCompleteCurrentRecord(TimelineRecordType::RunLoop);
+        m_didStartRecordingRunLoop = false;
+    });
+
+    m_frameStartObserver->schedule(currentRunLoop(), kCFRunLoopAfterWaiting | kCFRunLoopBeforeTimers);
+    m_frameStopObserver->schedule(currentRunLoop(), kCFRunLoopBeforeWaiting | kCFRunLoopExit);
+
+    // Create a runloop record immediately in order to capture the rest of the current runloop.
+    pushCurrentRecord(InspectorObject::create(), TimelineRecordType::RunLoop, false, nullptr);
+    m_didStartRecordingRunLoop = true;
+#endif
+
     if (m_frontendDispatcher)
         m_frontendDispatcher->recordingStarted();
 }
@@ -141,6 +195,11 @@
     if (m_scriptDebugServer)
         m_scriptDebugServer->removeListener(this, true);
 
+#if PLATFORM(COCOA)
+    m_frameStartObserver = nullptr;
+    m_frameStopObserver = nullptr;
+#endif
+
     clearRecordStack();
 
     m_enabled = false;
@@ -539,6 +598,8 @@
         return Inspector::Protocol::Timeline::EventType::Layout;
     case TimelineRecordType::Paint:
         return Inspector::Protocol::Timeline::EventType::Paint;
+    case TimelineRecordType::RunLoop:
+        return Inspector::Protocol::Timeline::EventType::RunLoop;
     case TimelineRecordType::ScrollLayer:
         return Inspector::Protocol::Timeline::EventType::ScrollLayer;
 
@@ -654,6 +715,7 @@
     , m_client(client)
     , m_enabled(false)
     , m_enabledFromFrontend(false)
+    , m_didStartRecordingRunLoop(false)
 {
 }
 

Modified: trunk/Source/WebCore/inspector/InspectorTimelineAgent.h (181624 => 181625)


--- trunk/Source/WebCore/inspector/InspectorTimelineAgent.h	2015-03-17 08:39:05 UTC (rev 181624)
+++ trunk/Source/WebCore/inspector/InspectorTimelineAgent.h	2015-03-17 08:41:19 UTC (rev 181625)
@@ -61,6 +61,7 @@
 class RenderObject;
 class ResourceRequest;
 class ResourceResponse;
+class RunLoopObserver;
 
 typedef String ErrorString;
 
@@ -71,6 +72,7 @@
     InvalidateLayout,
     Layout,
     Paint,
+    RunLoop,
     ScrollLayer,
 
     ParseHTML,
@@ -244,6 +246,12 @@
 
     bool m_enabled;
     bool m_enabledFromFrontend;
+
+#if PLATFORM(COCOA)
+    std::unique_ptr<WebCore::RunLoopObserver> m_frameStartObserver;
+    std::unique_ptr<WebCore::RunLoopObserver> m_frameStopObserver;
+#endif
+    bool m_didStartRecordingRunLoop;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/cf/RunLoopObserver.cpp (181624 => 181625)


--- trunk/Source/WebCore/platform/cf/RunLoopObserver.cpp	2015-03-17 08:39:05 UTC (rev 181624)
+++ trunk/Source/WebCore/platform/cf/RunLoopObserver.cpp	2015-03-17 08:41:19 UTC (rev 181625)
@@ -49,7 +49,7 @@
     m_callback();
 }
 
-void RunLoopObserver::schedule(CFRunLoopRef runLoop)
+void RunLoopObserver::schedule(CFRunLoopRef runLoop, CFRunLoopActivity activity)
 {
     if (!runLoop)
         runLoop = CFRunLoopGetCurrent();
@@ -61,7 +61,7 @@
         return;
 
     CFRunLoopObserverContext context = { 0, this, 0, 0, 0 };
-    m_runLoopObserver = adoptCF(CFRunLoopObserverCreate(0, kCFRunLoopBeforeWaiting | kCFRunLoopExit, true, m_order, runLoopObserverFired, &context));
+    m_runLoopObserver = adoptCF(CFRunLoopObserverCreate(0, activity, true, m_order, runLoopObserverFired, &context));
 
     CFRunLoopAddObserver(runLoop, m_runLoopObserver.get(), kCFRunLoopCommonModes);
 }

Modified: trunk/Source/WebCore/platform/cf/RunLoopObserver.h (181624 => 181625)


--- trunk/Source/WebCore/platform/cf/RunLoopObserver.h	2015-03-17 08:39:05 UTC (rev 181624)
+++ trunk/Source/WebCore/platform/cf/RunLoopObserver.h	2015-03-17 08:41:19 UTC (rev 181625)
@@ -42,7 +42,7 @@
 
     WEBCORE_EXPORT ~RunLoopObserver();
 
-    WEBCORE_EXPORT void schedule(CFRunLoopRef = nullptr);
+    WEBCORE_EXPORT void schedule(CFRunLoopRef = nullptr, CFRunLoopActivity = kCFRunLoopBeforeWaiting | kCFRunLoopExit);
     WEBCORE_EXPORT void invalidate();
 
     bool isScheduled() const { return m_runLoopObserver; }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to