Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs-developer/CHANGELOG-formats.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ Note that this is not an exhaustive list. Processed profile format upgraders can

## Processed profile format

### Version 72

Marker schemas now include a `style` field that controls their appearance in timeline marker tracks. It specifies the marker's background, position, height, corner shape, and optional border colors. The upgrader derives styles for older profiles.

### Version 71

The frame table (`profile.shared.frameTable`) representation changed in such a way that all its columns can now be typed arrays when using [JsonSlabs](https://github.com/mstange/json-slabs/) profiles.
Expand Down
2 changes: 1 addition & 1 deletion src/app-logic/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const GECKO_PROFILE_VERSION = 36;
// The current version of the "processed" profile format.
// Please don't forget to update the processed profile format changelog in
// `docs-developer/CHANGELOG-formats.md`.
export const PROCESSED_PROFILE_VERSION = 71;
export const PROCESSED_PROFILE_VERSION = 72;

// The following are the margin sizes for the left and right of the timeline. Independent
// components need to share these values.
Expand Down
54 changes: 42 additions & 12 deletions src/components/timeline/Markers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,18 @@ import { InView } from 'react-intersection-observer';
import {
overlayFills,
getMarkerStyle,
getMarkerStyleColor,
} from 'firefox-profiler/profile-logic/marker-styles';
import { getSchemaFromMarker } from 'firefox-profiler/profile-logic/marker-schema';
import { withSize } from 'firefox-profiler/components/shared/WithSize';
import { Tooltip } from 'firefox-profiler/components/tooltip/Tooltip';
import { TooltipMarker } from 'firefox-profiler/components/tooltip/Marker';
import { timeCode } from 'firefox-profiler/utils/time-code';
import explicitConnect from 'firefox-profiler/utils/connect';
import { getPreviewSelectionIsBeingModified } from 'firefox-profiler/selectors/profile';
import {
getMarkerSchemaByName,
getPreviewSelectionIsBeingModified,
} from 'firefox-profiler/selectors/profile';
import { getThreadSelectorsFromThreadsKey } from 'firefox-profiler/selectors/per-thread';
import { getSelectedThreadIndexes } from 'firefox-profiler/selectors/url-state';
import { changeRightClickedMarker } from 'firefox-profiler/actions/profile-view';
Expand All @@ -28,6 +33,7 @@ import type {
Marker,
MarkerIndex,
MarkerDisplayLocation,
MarkerSchemaByName,
ThreadsKey,
} from 'firefox-profiler/types';

Expand All @@ -52,6 +58,7 @@ type CanvasProps = {
readonly height: CssPixels;
readonly getMarker: (param: MarkerIndex) => Marker;
readonly markerIndexes: MarkerIndex[];
readonly markerSchemaByName: MarkerSchemaByName;
readonly hoveredMarker: Marker | null;
readonly mouseDownMarker: Marker | null;
readonly rightClickedMarker: Marker | null;
Expand Down Expand Up @@ -109,8 +116,15 @@ class TimelineMarkersCanvas extends React.PureComponent<CanvasProps> {
}

drawCanvas(c: HTMLCanvasElement) {
const { rangeStart, rangeEnd, width, height, getMarker, markerIndexes } =
this.props;
const {
rangeStart,
rangeEnd,
width,
height,
getMarker,
markerIndexes,
markerSchemaByName,
} = this.props;

if (height === 0 || width === 0) {
// bail out early if the size isn't known yet.
Expand Down Expand Up @@ -154,8 +168,9 @@ class TimelineMarkersCanvas extends React.PureComponent<CanvasProps> {
MIN_MARKER_WIDTH / devicePixelRatio
)
: Number.MAX_SAFE_INTEGER;
const markerStyle = getMarkerStyle(marker);
ctx.fillStyle = markerStyle.getBackground();
const markerSchema = getSchemaFromMarker(markerSchemaByName, marker.data);
const markerStyle = getMarkerStyle(marker.name, markerSchema);
ctx.fillStyle = getMarkerStyleColor(markerStyle.background);
if (markerStyle.squareCorners) {
ctx.fillRect(pos, markerStyle.top, itemWidth, markerStyle.height);
} else {
Expand All @@ -168,12 +183,12 @@ class TimelineMarkersCanvas extends React.PureComponent<CanvasProps> {
1 / devicePixelRatio
);
}
if (markerStyle.hasBorderLeft()) {
ctx.fillStyle = markerStyle.getBorderLeft();
if (markerStyle.borderLeft !== null) {
ctx.fillStyle = getMarkerStyleColor(markerStyle.borderLeft);
ctx.fillRect(pos, markerStyle.top, 1, markerStyle.height);
}
if (markerStyle.hasBorderRight()) {
ctx.fillStyle = markerStyle.getBorderRight();
if (markerStyle.borderRight !== null) {
ctx.fillStyle = getMarkerStyleColor(markerStyle.borderRight);
ctx.fillRect(
pos + itemWidth - 1,
markerStyle.top,
Expand Down Expand Up @@ -302,6 +317,7 @@ export type StateProps = {
readonly additionalClassName?: string | null;
readonly getMarker: (param: MarkerIndex) => Marker;
readonly markerIndexes: MarkerIndex[];
readonly markerSchemaByName: MarkerSchemaByName;
readonly isSelected: boolean;
readonly isModifyingSelection: boolean;
readonly testId: string;
Expand Down Expand Up @@ -332,8 +348,14 @@ class TimelineMarkers extends React.PureComponent<Props, State> {
_hitTest(e: React.MouseEvent<HTMLCanvasElement>): MarkerIndex | null {
const c = e.currentTarget;
const r = c.getBoundingClientRect();
const { width, rangeStart, rangeEnd, getMarker, markerIndexes } =
this.props;
const {
width,
rangeStart,
rangeEnd,
getMarker,
markerIndexes,
markerSchemaByName,
} = this.props;
const x = e.pageX - r.left;
const y = e.pageY - r.top;
const rangeLength = rangeEnd - rangeStart;
Expand All @@ -354,7 +376,8 @@ class TimelineMarkers extends React.PureComponent<Props, State> {
continue;
}

const markerStyle = getMarkerStyle(marker);
const markerSchema = getSchemaFromMarker(markerSchemaByName, marker.data);
const markerStyle = getMarkerStyle(marker.name, markerSchema);

if (y >= markerStyle.top && y < markerStyle.top + markerStyle.height) {
return markerIndex;
Expand Down Expand Up @@ -491,6 +514,7 @@ class TimelineMarkers extends React.PureComponent<Props, State> {
rangeEnd={this.props.rangeEnd}
getMarker={this.props.getMarker}
markerIndexes={this.props.markerIndexes}
markerSchemaByName={this.props.markerSchemaByName}
hoveredMarker={hoveredMarker}
mouseDownMarker={mouseDownMarker}
rightClickedMarker={rightClickedMarker}
Expand Down Expand Up @@ -539,6 +563,7 @@ export const TimelineMarkersJank = explicitConnect<

return {
getMarker: selectors.getMarkerGetter(state),
markerSchemaByName: getMarkerSchemaByName(state),
// These don't use marker schema as they are derived.
markerIndexes: selectors.getTimelineJankMarkerIndexes(state),
isSelected: _getTimelineMarkersIsSelected(selectedThreads, threadsKey),
Expand Down Expand Up @@ -569,6 +594,7 @@ export const TimelineMarkersOverview = explicitConnect<
? 'timelineMarkersGeckoMain'
: null,
getMarker: selectors.getMarkerGetter(state),
markerSchemaByName: getMarkerSchemaByName(state),
markerIndexes: selectors.getTimelineOverviewMarkerIndexes(state),
isSelected: _getTimelineMarkersIsSelected(selectedThreads, threadsKey),
isModifyingSelection: getPreviewSelectionIsBeingModified(state),
Expand All @@ -595,6 +621,7 @@ export const TimelineMarkersFileIo = explicitConnect<

return {
getMarker: selectors.getMarkerGetter(state),
markerSchemaByName: getMarkerSchemaByName(state),
markerIndexes: selectors.getTimelineFileIoMarkerIndexes(state),
isSelected: _getTimelineMarkersIsSelected(selectedThreads, threadsKey),
isModifyingSelection: getPreviewSelectionIsBeingModified(state),
Expand All @@ -621,6 +648,7 @@ export const TimelineMarkersMemory = explicitConnect<

return {
getMarker: selectors.getMarkerGetter(state),
markerSchemaByName: getMarkerSchemaByName(state),
markerIndexes: selectors.getTimelineMemoryMarkerIndexes(state),
isSelected: _getTimelineMarkersIsSelected(selectedThreads, threadsKey),
isModifyingSelection: getPreviewSelectionIsBeingModified(state),
Expand Down Expand Up @@ -648,6 +676,7 @@ export const TimelineMarkersIPC = explicitConnect<

return {
getMarker: selectors.getMarkerGetter(state),
markerSchemaByName: getMarkerSchemaByName(state),
markerIndexes: selectors.getTimelineIPCMarkerIndexes(state),
isSelected: _getTimelineMarkersIsSelected(selectedThreads, threadsKey),
isModifyingSelection: getPreviewSelectionIsBeingModified(state),
Expand Down Expand Up @@ -695,6 +724,7 @@ export const TimelineMarkersCounter = explicitConnect<

return {
getMarker: selectors.getMarkerGetter(state),
markerSchemaByName: getMarkerSchemaByName(state),
markerIndexes:
selectors.getTimelineMarkerIndexesBySchemaLocation(
markerSchemaLocation
Expand Down
1 change: 0 additions & 1 deletion src/profile-logic/gecko-profile-versioning.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1578,7 +1578,6 @@ const _upgraders: {
// marker schema. This bump is only here so that older frontends, which read
// these two fields directly, get updated.
},

// If you add a new upgrader here, please document the change in
// `docs-developer/CHANGELOG-formats.md`.
};
Expand Down
3 changes: 3 additions & 0 deletions src/profile-logic/import/chrome.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {

import { getTimeRangeForThread } from '../profile-data';
import { GlobalDataCollector } from '../global-data-collector';
import { getMarkerSchemaStyleFallback } from '../marker-styles';

// Chrome Tracing Event Spec:
// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
Expand Down Expand Up @@ -993,6 +994,7 @@ function extractMarkers(
profile.meta.markerSchema = [
{
name: 'EventDispatch',
style: getMarkerSchemaStyleFallback('EventDispatch'),
chartLabel: '{marker.data.type2}',
tooltipLabel: '{marker.data.type2} - EventDispatch',
tableLabel: '{marker.data.type2}',
Expand Down Expand Up @@ -1091,6 +1093,7 @@ function extractMarkers(
// generates Source markers, ParseDeclarationOrFunctionDefinition markers,
// and similar compiler events with file paths or location details.
name: 'EventWithDetail',
style: getMarkerSchemaStyleFallback('EventWithDetail'),
chartLabel: '{marker.data.detail}',
tooltipLabel: '{marker.name}: {marker.data.detail}',
tableLabel: '{marker.data.detail}',
Expand Down
4 changes: 4 additions & 0 deletions src/profile-logic/marker-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import type {
Pid,
} from 'firefox-profiler/types';
import type { StringTable } from '../utils/string-table';
import { getMarkerSchemaStyleFallback } from './marker-styles';

/**
* The marker schema comes from Gecko, and is embedded in the profile. However,
Expand All @@ -37,6 +38,7 @@ import type { StringTable } from '../utils/string-table';
export const markerSchemaFrontEndOnly: MarkerSchema[] = [
{
name: 'Jank',
style: getMarkerSchemaStyleFallback('Jank'),
display: ['marker-table', 'marker-chart'],
tooltipLabel: 'Jank – event processing delay',
tableLabel: 'Event processing delay',
Expand All @@ -51,6 +53,7 @@ export const markerSchemaFrontEndOnly: MarkerSchema[] = [
// for IPC, the Gecko ones get overwritten by this definition.
{
name: 'IPC',
style: getMarkerSchemaStyleFallback('IPC'),
tooltipLabel: 'IPC — {marker.data.niceDirection}',
tableLabel: '{marker.data.messageType} — {marker.data.niceDirection}',
chartLabel: '{marker.data.messageType}',
Expand All @@ -68,6 +71,7 @@ export const markerSchemaFrontEndOnly: MarkerSchema[] = [
// `display` property is used to decide where to display these markers, and
// we need it to hide them from the marker chart.
name: 'Network',
style: getMarkerSchemaStyleFallback('Network'),
display: ['marker-table', 'marker-chart', 'timeline-network'],
chartLabel: '{marker.data.URI}',
fields: [
Expand Down
Loading
Loading