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
7 changes: 3 additions & 4 deletions src/components/shared/thread/ActivityGraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import type {
CategoryList,
ImplementationFilter,
IndexIntoSamplesTable,
SelectedState,
Milliseconds,
CssPixels,
TimelineType,
Expand All @@ -45,7 +44,7 @@ export type Props = {
sampleIndex: IndexIntoSamplesTable | null
) => void;
readonly categories: CategoryList;
readonly samplesSelectedStates: null | SelectedState[];
readonly sampleSelectedStates: Uint8Array;
readonly treeOrderSampleComparator: (
a: IndexIntoSamplesTable,
b: IndexIntoSamplesTable
Expand Down Expand Up @@ -135,7 +134,7 @@ class ThreadActivityGraphImpl extends React.PureComponent<Props, State> {
rangeStart,
rangeEnd,
sampleIndexOffset,
samplesSelectedStates,
sampleSelectedStates,
treeOrderSampleComparator,
enableCPUUsage,
implementationFilter,
Expand Down Expand Up @@ -164,7 +163,7 @@ class ThreadActivityGraphImpl extends React.PureComponent<Props, State> {
rangeStart={rangeStart}
rangeEnd={rangeEnd}
sampleIndexOffset={sampleIndexOffset}
samplesSelectedStates={samplesSelectedStates}
sampleSelectedStates={sampleSelectedStates}
treeOrderSampleComparator={treeOrderSampleComparator}
categories={categories}
passFillsQuerier={this._setFillsQuerier}
Expand Down
7 changes: 3 additions & 4 deletions src/components/shared/thread/ActivityGraphCanvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import { mapCategoryColorNameToStyles } from 'firefox-profiler/utils/colors';
import type {
Thread,
Milliseconds,
SelectedState,
IndexIntoSamplesTable,
CategoryList,
} from 'firefox-profiler/types';
Expand All @@ -30,7 +29,7 @@ type CanvasProps = {
readonly rangeStart: Milliseconds;
readonly rangeEnd: Milliseconds;
readonly sampleIndexOffset: number;
readonly samplesSelectedStates: null | SelectedState[];
readonly sampleSelectedStates: Uint8Array;
readonly treeOrderSampleComparator: (
a: IndexIntoSamplesTable,
b: IndexIntoSamplesTable
Expand Down Expand Up @@ -131,7 +130,7 @@ export class ActivityGraphCanvas extends React.PureComponent<CanvasProps> {
rangeStart,
rangeEnd,
sampleIndexOffset,
samplesSelectedStates,
sampleSelectedStates,
treeOrderSampleComparator,
enableCPUUsage,
width,
Expand All @@ -153,7 +152,7 @@ export class ActivityGraphCanvas extends React.PureComponent<CanvasProps> {
rangeStart,
rangeEnd,
sampleIndexOffset,
samplesSelectedStates,
sampleSelectedStates,
enableCPUUsage,
xPixelsPerMs: canvasPixelWidth / (rangeEnd - rangeStart),
treeOrderSampleComparator,
Expand Down
133 changes: 40 additions & 93 deletions src/components/shared/thread/ActivityGraphFills.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ type RenderedComponentSettings = {
readonly treeOrderSampleComparator:
| ((a: IndexIntoSamplesTable, b: IndexIntoSamplesTable) => number)
| null;
readonly samplesSelectedStates: null | Array<SelectedState>;
readonly sampleSelectedStates: Uint8Array;
readonly categoryDrawStyles: CategoryDrawStyles;
};

Expand Down Expand Up @@ -75,20 +75,17 @@ export type CategoryDrawStyles = ReadonlyArray<{
readonly filteredOutByTransformFillStyle: CanvasPattern | string;
}>;

type SelectedPercentageAtPixelBuffers = {
// These Float32Arrays are mutated in place during the computation step.
readonly beforeSelectedPercentageAtPixel: Float32Array<ArrayBuffer>;
readonly selectedPercentageAtPixel: Float32Array<ArrayBuffer>;
readonly afterSelectedPercentageAtPixel: Float32Array<ArrayBuffer>;
readonly filteredOutByTransformPercentageAtPixel: Float32Array<ArrayBuffer>;
readonly filteredOutByTabPercentageAtPixel: Float32Array<ArrayBuffer>;
};
// These Float32Arrays are mutated in place during the computation step.
// buffers[selectedState] is the buffer for the given SelectedState.
type SelectedPercentageAtPixelBuffers = Float32Array<ArrayBuffer>[];

export type CpuRatioInTimeRange = {
readonly cpuRatio: number;
readonly timeRange: Milliseconds;
};

const SELECTED_STATE_BUFFER_COUNT = 4;

const BOX_BLUR_RADII = [3, 2, 2];
const SMOOTHING_RADIUS = 3 + 2 + 2;
const SMOOTHING_KERNEL: Float32Array<ArrayBuffer> = _getSmoothingKernel(
Expand Down Expand Up @@ -218,6 +215,8 @@ export class ActivityGraphFillComputer {
interval,
enableCPUUsage,
sampleIndexOffset,
rangeStart,
sampleSelectedStates,
} = this.renderedComponentSettings;

if (samples.length === 0) {
Expand Down Expand Up @@ -249,15 +248,19 @@ export class ActivityGraphFillComputer {
afterSampleCpuRatio = threadCPURatio[i + 1];
}

// Mutate the percentage buffers.
this._accumulateInCategory(
category,
i,
const percentageBuffers = this.mutablePercentageBuffers[category];
const selectedState = sampleSelectedStates[i];
const percentageBuffer = percentageBuffers[selectedState];

_accumulateInBuffer(
percentageBuffer,
this.renderedComponentSettings,
prevSampleTime,
sampleTime,
nextSampleTime,
beforeSampleCpuRatio,
afterSampleCpuRatio
afterSampleCpuRatio,
rangeStart
);

prevSampleTime = sampleTime;
Expand Down Expand Up @@ -288,36 +291,11 @@ export class ActivityGraphFillComputer {
}
}

this._accumulateInCategory(
lastSampleCategory,
samples.length - 1,
prevSampleTime,
sampleTime,
sampleTime + interval,
beforeSampleCpuRatio,
afterSampleCpuRatio
);
}
const nextSampleTime = sampleTime + interval;
const percentageBuffers = this.mutablePercentageBuffers[lastSampleCategory];

/**
* Mutate the percentage buffers, by taking this category, and accumulating its
* percentage into the buffer.
*/
_accumulateInCategory(
category: IndexIntoCategoryList,
sampleIndex: IndexIntoSamplesTable,
prevSampleTime: Milliseconds,
sampleTime: Milliseconds,
nextSampleTime: Milliseconds,
beforeSampleCpuRatio: number,
afterSampleCpuRatio: number
) {
const { rangeStart } = this.renderedComponentSettings;
const percentageBuffers = this.mutablePercentageBuffers[category];
const percentageBuffer = this._pickPercentageBuffer(
percentageBuffers,
sampleIndex
);
const selectedState = sampleSelectedStates[lastIdx];
const percentageBuffer = percentageBuffers[selectedState];

_accumulateInBuffer(
percentageBuffer,
Expand All @@ -330,31 +308,6 @@ export class ActivityGraphFillComputer {
rangeStart
);
}

/**
* Pick the correct percentage buffer based on the sample state.
*/
_pickPercentageBuffer(
percentageBuffers: SelectedPercentageAtPixelBuffers,
sampleIndex: IndexIntoSamplesTable
): Float32Array {
const { samplesSelectedStates } = this.renderedComponentSettings;
if (!samplesSelectedStates) {
return percentageBuffers.selectedPercentageAtPixel;
}
switch (samplesSelectedStates[sampleIndex]) {
case SelectedState.FilteredOutByTransform:
return percentageBuffers.filteredOutByTransformPercentageAtPixel;
case SelectedState.UnselectedOrderedBeforeSelected:
return percentageBuffers.beforeSelectedPercentageAtPixel;
case SelectedState.Selected:
return percentageBuffers.selectedPercentageAtPixel;
case SelectedState.UnselectedOrderedAfterSelected:
return percentageBuffers.afterSelectedPercentageAtPixel;
default:
throw new Error('Unexpected samplesSelectedStates value');
}
}
}

/**
Expand Down Expand Up @@ -739,15 +692,13 @@ function _createSelectedPercentageAtPixelBuffers({
categoryDrawStyles: CategoryDrawStyles;
canvasPixelWidth: number;
}): SelectedPercentageAtPixelBuffers[] {
return categoryDrawStyles.map(() => ({
beforeSelectedPercentageAtPixel: new Float32Array(canvasPixelWidth),
selectedPercentageAtPixel: new Float32Array(canvasPixelWidth),
afterSelectedPercentageAtPixel: new Float32Array(canvasPixelWidth),
filteredOutByTransformPercentageAtPixel: new Float32Array(canvasPixelWidth),
// Unlike other fields, we do not mutate that array and we keep that zero
// array to indicate that we don't want to draw anything for this case.
filteredOutByTabPercentageAtPixel: new Float32Array(canvasPixelWidth),
}));
return categoryDrawStyles.map(() => {
const percentageBuffers = [];
for (let i = 0; i < SELECTED_STATE_BUFFER_COUNT; i++) {
percentageBuffers[i] = new Float32Array(canvasPixelWidth);
}
return percentageBuffers;
});
}

/**
Expand All @@ -774,39 +725,35 @@ function _getCategoryFills(
(categoryIndex) => {
const categoryDrawStyle = categoryDrawStyles[categoryIndex];
const buffer = percentageBuffers[categoryIndex];
const canvasPixelWidth =
buffer[SelectedState.UnselectedOrderedBeforeSelected].length;
// For every category we draw four fills, for the four selection kinds:
return [
{
category: categoryDrawStyle.category,
fillStyle: categoryDrawStyle.getUnselectedFillStyle(),
perPixelContribution: buffer.beforeSelectedPercentageAtPixel,
accumulatedUpperEdge: new Float32Array(
buffer.beforeSelectedPercentageAtPixel.length
),
perPixelContribution:
buffer[SelectedState.UnselectedOrderedBeforeSelected],
accumulatedUpperEdge: new Float32Array(canvasPixelWidth),
},
{
category: categoryDrawStyle.category,
fillStyle: categoryDrawStyle.getSelectedFillStyle(),
perPixelContribution: buffer.selectedPercentageAtPixel,
accumulatedUpperEdge: new Float32Array(
buffer.beforeSelectedPercentageAtPixel.length
),
perPixelContribution: buffer[SelectedState.Selected],
accumulatedUpperEdge: new Float32Array(canvasPixelWidth),
},
{
category: categoryDrawStyle.category,
fillStyle: categoryDrawStyle.getUnselectedFillStyle(),
perPixelContribution: buffer.afterSelectedPercentageAtPixel,
accumulatedUpperEdge: new Float32Array(
buffer.beforeSelectedPercentageAtPixel.length
),
perPixelContribution:
buffer[SelectedState.UnselectedOrderedAfterSelected],
accumulatedUpperEdge: new Float32Array(canvasPixelWidth),
},
{
category: categoryDrawStyle.category,
fillStyle: categoryDrawStyle.filteredOutByTransformFillStyle,
perPixelContribution: buffer.filteredOutByTransformPercentageAtPixel,
accumulatedUpperEdge: new Float32Array(
buffer.beforeSelectedPercentageAtPixel.length
),
perPixelContribution: buffer[SelectedState.FilteredOutByTransform],
accumulatedUpperEdge: new Float32Array(canvasPixelWidth),
},
];
}
Expand Down
7 changes: 3 additions & 4 deletions src/components/shared/thread/CPUGraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,13 @@ import type {
CategoryList,
IndexIntoSamplesTable,
Milliseconds,
SelectedState,
} from 'firefox-profiler/types';
import type { CallNodeInfo } from 'firefox-profiler/profile-logic/call-node-info';

type Props = {
readonly className: string;
readonly thread: Thread;
readonly samplesSelectedStates: null | SelectedState[];
readonly sampleSelectedStates: null | Uint8Array;
readonly interval: Milliseconds;
readonly rangeStart: Milliseconds;
readonly rangeEnd: Milliseconds;
Expand Down Expand Up @@ -51,7 +50,7 @@ export class ThreadCPUGraph extends PureComponent<Props> {
const {
className,
thread,
samplesSelectedStates,
sampleSelectedStates,
interval,
rangeStart,
rangeEnd,
Expand All @@ -71,7 +70,7 @@ export class ThreadCPUGraph extends PureComponent<Props> {
trackName={trackName}
interval={interval}
thread={thread}
samplesSelectedStates={samplesSelectedStates}
sampleSelectedStates={sampleSelectedStates}
rangeStart={rangeStart}
rangeEnd={rangeEnd}
categories={categories}
Expand Down
8 changes: 4 additions & 4 deletions src/components/shared/thread/HeightGraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type Props = {
readonly maxValue: number;
readonly className: string;
readonly thread: Thread;
readonly samplesSelectedStates: null | SelectedState[];
readonly sampleSelectedStates: null | Uint8Array;
readonly interval: Milliseconds;
readonly rangeStart: Milliseconds;
readonly rangeEnd: Milliseconds;
Expand Down Expand Up @@ -64,7 +64,7 @@ export class ThreadHeightGraph extends PureComponent<Props> {
drawCanvas(canvas: HTMLCanvasElement) {
const {
thread,
samplesSelectedStates,
sampleSelectedStates,
interval,
rangeStart,
rangeEnd,
Expand Down Expand Up @@ -137,8 +137,8 @@ export class ThreadHeightGraph extends PureComponent<Props> {
const xPos = (sampleTime - range[0]) * xPixelsPerMs;
let samplesBucket;
if (
samplesSelectedStates !== null &&
samplesSelectedStates[i] === SelectedState.Selected
sampleSelectedStates !== null &&
sampleSelectedStates[i] === (SelectedState.Selected as number)
) {
samplesBucket = highlightedSamples;
} else {
Expand Down
Loading