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; }