Bug 1211841 - Style off the main thread markers differently, r=jsantell
authorVictor Porof <vporof@mozilla.com>
Wed, 28 Oct 2015 11:00:52 +0100
changeset 269941 594d0213bc5c87f2286ddb8ae486dc3f8e5b9ac5
parent 269940 a5a31b8a5383c1683e73e7e470e2e95b55aff8a6
child 269942 a6dcceafce9c3279fbba099f8c439934333b00d7
push id29595
push userkwierso@gmail.com
push dateWed, 28 Oct 2015 23:41:46 +0000
treeherdermozilla-central@769f29c92bb2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjsantell
bugs1211841
milestone44.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1211841 - Style off the main thread markers differently, r=jsantell
devtools/client/performance/modules/widgets/marker-view.js
devtools/client/performance/test/browser_timeline-waterfall-workers.js
devtools/client/themes/performance.css
docshell/base/timeline/AbstractTimelineMarker.cpp
docshell/base/timeline/AbstractTimelineMarker.h
docshell/base/timeline/CompositeTimelineMarker.h
docshell/base/timeline/moz.build
view/nsView.cpp
--- a/devtools/client/performance/modules/widgets/marker-view.js
+++ b/devtools/client/performance/modules/widgets/marker-view.js
@@ -105,16 +105,17 @@ MarkerView.prototype = Heritage.extend(A
    * Creates the view for this waterfall node.
    * @param nsIDOMNode document
    * @param nsIDOMNode arrowNode
    * @return nsIDOMNode
    */
   _displaySelf: function(document, arrowNode) {
     let targetNode = document.createElement("hbox");
     targetNode.className = "waterfall-tree-item";
+    targetNode.setAttribute("otmt", this.marker.isOffMainThread);
 
     if (this == this.root) {
       // Bounds are needed for properly positioning and scaling markers in
       // the waterfall, but it's sufficient to make those calculations only
       // for the root node.
       this.root.recalculateBounds();
       // The AbstractTreeItem propagates events to the root, so we don't
       // need to listen them on descendant items in the tree.
--- a/devtools/client/performance/test/browser_timeline-waterfall-workers.js
+++ b/devtools/client/performance/test/browser_timeline-waterfall-workers.js
@@ -2,17 +2,17 @@
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
  * Tests if the sidebar is properly updated with worker markers.
  */
 
 function* spawnTest() {
   let { panel } = yield initPerformance(WORKER_URL);
-  let { PerformanceController } = panel.panelWin;
+  let { $$, $, PerformanceController } = panel.panelWin;
 
   loadFrameScripts();
 
   yield startRecording(panel);
   ok(true, "Recording has started.");
 
   evalInDebuggee("performWork()");
 
@@ -22,36 +22,53 @@ function* spawnTest() {
     if (!markers.some(m => m.name == "Worker") ||
         !markers.some(m => m.workerOperation == "serializeDataOffMainThread") ||
         !markers.some(m => m.workerOperation == "serializeDataOnMainThread") ||
         !markers.some(m => m.workerOperation == "deserializeDataOffMainThread") ||
         !markers.some(m => m.workerOperation == "deserializeDataOnMainThread")) {
       return false;
     }
 
-    testWorkerMarker(markers.find(m => m.name == "Worker"));
+    testWorkerMarkerData(markers.find(m => m.name == "Worker"));
     return true;
   });
 
   yield stopRecording(panel);
   ok(true, "Recording has ended.");
 
+  for (let node of $$(".waterfall-marker-name[value=Worker")) {
+    testWorkerMarkerUI(node.parentNode.parentNode);
+  }
+
   yield teardown(panel);
   finish();
 }
 
-function testWorkerMarker(marker) {
+function testWorkerMarkerData(marker) {
   ok(true, "Found a worker marker.");
 
   ok("start" in marker,
     "The start time is specified in the worker marker.");
   ok("end" in marker,
     "The end time is specified in the worker marker.");
+
   ok("workerOperation" in marker,
     "The worker operation is specified in the worker marker.");
+
+  ok("processType" in marker,
+    "The process type is specified in the worker marker.");
+  ok("isOffMainThread" in marker,
+    "The thread origin is specified in the worker marker.");
+}
+
+function testWorkerMarkerUI(node) {
+  is(node.className, "waterfall-tree-item",
+    "The marker node has the correct class name.");
+  ok(node.hasAttribute("otmt"),
+    "The marker node specifies if it is off the main thread or not.");
 }
 
 /**
  * Takes a string `script` and evaluates it directly in the content
  * in potentially a different process.
  */
 function evalInDebuggee (script) {
   let { generateUUID } = Cc['@mozilla.org/uuid-generator;1'].getService(Ci.nsIUUIDGenerator);
--- a/devtools/client/themes/performance.css
+++ b/devtools/client/themes/performance.css
@@ -501,16 +501,27 @@
 
 .waterfall-marker > .theme-twisty {
   /* Don't affect layout. */
   width: 14px;
   -moz-margin-end: -14px;
 }
 
 /**
+ * OTMT markers
+ */
+
+.waterfall-tree-item[otmt=true] .waterfall-marker-bullet,
+.waterfall-tree-item[otmt=true] .waterfall-marker-bar {
+  background-color: transparent;
+  border-width: 1px;
+  border-style: solid;
+}
+
+/**
  * Marker details view
  */
 
 #waterfall-details {
   -moz-padding-start: 8px;
   -moz-padding-end: 8px;
   padding-top: 2vh;
   overflow: auto;
@@ -547,53 +558,63 @@
 
 /**
  * Marker colors
  */
 
 menuitem.marker-color-graphs-full-red:before,
 .marker-color-graphs-full-red {
   background-color: var(--theme-graphs-full-red);
+  border-color: var(--theme-graphs-full-red);
 }
 menuitem.marker-color-graphs-full-blue:before,
 .marker-color-graphs-full-blue {
   background-color: var(--theme-graphs-full-blue);
+  border-color: var(--theme-graphs-full-blue);
 }
 
 menuitem.marker-color-graphs-green:before,
 .marker-color-graphs-green {
   background-color: var(--theme-graphs-green);
+  border-color: var(--theme-graphs-green);
 }
 menuitem.marker-color-graphs-blue:before,
 .marker-color-graphs-blue {
   background-color: var(--theme-graphs-blue);
+  border-color: var(--theme-graphs-blue);
 }
 menuitem.marker-color-graphs-bluegrey:before,
 .marker-color-graphs-bluegrey {
   background-color: var(--theme-graphs-bluegrey);
+  border-color: var(--theme-graphs-bluegrey);
 }
 menuitem.marker-color-graphs-purple:before,
 .marker-color-graphs-purple {
   background-color: var(--theme-graphs-purple);
+  border-color: var(--theme-graphs-purple);
 }
 menuitem.marker-color-graphs-yellow:before,
 .marker-color-graphs-yellow {
   background-color: var(--theme-graphs-yellow);
+  border-color: var(--theme-graphs-yellow);
 }
 menuitem.marker-color-graphs-orange:before,
 .marker-color-graphs-orange {
   background-color: var(--theme-graphs-orange);
+  border-color: var(--theme-graphs-orange);
 }
 menuitem.marker-color-graphs-red:before,
 .marker-color-graphs-red {
   background-color: var(--theme-graphs-red);
+  border-color: var(--theme-graphs-red);
 }
 menuitem.marker-color-graphs-grey:before,
 .marker-color-graphs-grey{
   background-color: var(--theme-graphs-grey);
+  border-color: var(--theme-graphs-grey);
 }
 
 /**
  * JIT View
  */
 
 #jit-optimizations-view {
   width: 350px;
--- a/docshell/base/timeline/AbstractTimelineMarker.cpp
+++ b/docshell/base/timeline/AbstractTimelineMarker.cpp
@@ -70,9 +70,21 @@ AbstractTimelineMarker::SetCustomTime(co
 }
 
 void
 AbstractTimelineMarker::SetCustomTime(DOMHighResTimeStamp aTime)
 {
   mTime = aTime;
 }
 
+void
+AbstractTimelineMarker::SetProcessType(GeckoProcessType aProcessType)
+{
+  mProcessType = aProcessType;
+}
+
+void
+AbstractTimelineMarker::SetOffMainThread(bool aIsOffMainThread)
+{
+  mIsOffMainThread = aIsOffMainThread;
+}
+
 } // namespace mozilla
--- a/docshell/base/timeline/AbstractTimelineMarker.h
+++ b/docshell/base/timeline/AbstractTimelineMarker.h
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_AbstractTimelineMarker_h_
 #define mozilla_AbstractTimelineMarker_h_
 
 #include "TimelineMarkerEnums.h" // for MarkerTracingType
 #include "nsDOMNavigationTiming.h" // for DOMHighResTimeStamp
+#include "nsXULAppAPI.h" // for GeckoProcessType
 #include "mozilla/UniquePtr.h"
 
 struct JSContext;
 class JSObject;
 
 namespace mozilla {
 class TimeStamp;
 
@@ -58,13 +59,15 @@ private:
 
   uint8_t mProcessType; // @see `enum GeckoProcessType`.
   bool mIsOffMainThread;
 
 protected:
   void SetCurrentTime();
   void SetCustomTime(const TimeStamp& aTime);
   void SetCustomTime(DOMHighResTimeStamp aTime);
+  void SetProcessType(GeckoProcessType aProcessType);
+  void SetOffMainThread(bool aIsOffMainThread);
 };
 
 } // namespace mozilla
 
 #endif /* mozilla_AbstractTimelineMarker_h_ */
new file mode 100644
--- /dev/null
+++ b/docshell/base/timeline/CompositeTimelineMarker.h
@@ -0,0 +1,33 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_CompositeTimelineMarker_h_
+#define mozilla_CompositeTimelineMarker_h_
+
+#include "TimelineMarker.h"
+#include "mozilla/dom/ProfileTimelineMarkerBinding.h"
+
+namespace mozilla {
+
+class CompositeTimelineMarker : public TimelineMarker
+{
+public:
+  explicit CompositeTimelineMarker(const TimeStamp& aTime,
+                                   MarkerTracingType aTracingType)
+    : TimelineMarker("Composite", aTime, aTracingType)
+  {
+    // Even though these markers end up being created on the main thread in the
+    // content or chrome processes, they actually trace down code in the
+    // compositor parent process. All the information for creating these markers
+    // is sent along via IPC to an nsView when a composite finishes.
+    // Mark this as 'off the main thread' to style it differently in frontends.
+    SetOffMainThread(true);
+  }
+};
+
+} // namespace mozilla
+
+#endif // mozilla_CompositeTimelineMarker_h_
--- a/docshell/base/timeline/moz.build
+++ b/docshell/base/timeline/moz.build
@@ -3,16 +3,17 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 EXPORTS.mozilla += [
     'AbstractTimelineMarker.h',
     'AutoGlobalTimelineMarker.h',
     'AutoTimelineMarker.h',
+    'CompositeTimelineMarker.h',
     'ConsoleTimelineMarker.h',
     'EventTimelineMarker.h',
     'JavascriptTimelineMarker.h',
     'LayerTimelineMarker.h',
     'MarkersStorage.h',
     'ObservedDocShell.h',
     'RestyleTimelineMarker.h',
     'TimelineConsumers.h',
--- a/view/nsView.cpp
+++ b/view/nsView.cpp
@@ -14,16 +14,17 @@
 #include "nsIWidget.h"
 #include "nsViewManager.h"
 #include "nsIFrame.h"
 #include "nsPresArena.h"
 #include "nsXULPopupManager.h"
 #include "nsIWidgetListener.h"
 #include "nsContentUtils.h" // for nsAutoScriptBlocker
 #include "mozilla/TimelineConsumers.h"
+#include "mozilla/CompositeTimelineMarker.h"
 
 using namespace mozilla;
 
 nsView::nsView(nsViewManager* aViewManager, nsViewVisibility aVisibility)
 {
   MOZ_COUNT_CTOR(nsView);
 
   mVis = aVisibility;
@@ -1093,19 +1094,19 @@ nsView::DidCompositeWindow(const TimeSta
       return;
     }
 
     nsIDocShell* docShell = context->GetDocShell();
     RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
 
     if (timelines && timelines->HasConsumer(docShell)) {
       timelines->AddMarkerForDocShell(docShell,
-        "Composite", aCompositeStart, MarkerTracingType::START);
+        MakeUnique<CompositeTimelineMarker>(aCompositeStart, MarkerTracingType::START));
       timelines->AddMarkerForDocShell(docShell,
-        "Composite", aCompositeEnd, MarkerTracingType::END);
+        MakeUnique<CompositeTimelineMarker>(aCompositeEnd, MarkerTracingType::END));
     }
   }
 }
 
 void
 nsView::RequestRepaint()
 {
   nsIPresShell* presShell = mViewManager->GetPresShell();