From b3f4f57464a1da0b249d9db0a3be90159288bf7c Mon Sep 17 00:00:00 2001 From: ahaoboy <504595380@qq.com> Date: Thu, 26 Sep 2024 13:56:58 +0800 Subject: [PATCH] timings: add toggle button --- src/cargo/core/compiler/timings.js | 857 +++++++++++++++-------------- src/cargo/core/compiler/timings.rs | 93 +++- 2 files changed, 512 insertions(+), 438 deletions(-) diff --git a/src/cargo/core/compiler/timings.js b/src/cargo/core/compiler/timings.js index 4e79f2c909f..1fde1b38ff4 100644 --- a/src/cargo/core/compiler/timings.js +++ b/src/cargo/core/compiler/timings.js @@ -24,472 +24,509 @@ let REVERSE_UNIT_DEPS = {}; let REVERSE_UNIT_RMETA_DEPS = {}; // Colors from css -const getCssColor = name => getComputedStyle(document.documentElement).getPropertyValue(name); -const TEXT_COLOR = getCssColor('--text'); -const BG_COLOR = getCssColor('--background'); -const CANVAS_BG = getCssColor('--canvas-background'); -const AXES_COLOR = getCssColor('--canvas-axes'); -const GRID_COLOR = getCssColor('--canvas-grid'); -const BLOCK_COLOR = getCssColor('--canvas-block'); -const CUSTOM_BUILD_COLOR = getCssColor('--canvas-custom-build'); -const NOT_CUSTOM_BUILD_COLOR = getCssColor('--canvas-not-custom-build'); -const DEP_LINE_COLOR = getCssColor('--canvas-dep-line'); -const DEP_LINE_HIGHLIGHTED_COLOR = getCssColor('--canvas-dep-line-highlighted'); -const CPU_COLOR = getCssColor('--canvas-cpu'); - -for (let n=0; n unit.duration >= min_time); - - const graph_height = Y_TICK_DIST * units.length; - const {ctx, graph_width, canvas_width, canvas_height, px_per_sec} = draw_graph_axes('pipeline-graph', graph_height); - const container = document.getElementById('pipeline-container'); - container.style.width = canvas_width; - container.style.height = canvas_height; - - // Canvas for hover highlights. This is a separate layer to improve performance. - const linectx = setup_canvas('pipeline-graph-lines', canvas_width, canvas_height); - linectx.clearRect(0, 0, canvas_width, canvas_height); - ctx.strokeStyle = AXES_COLOR; - // Draw Y tick marks. - for (let n=1; n getComputedStyle(document.body).getPropertyValue(name); + +function render(){ + const TEXT_COLOR = getCssColor('--text'); + const BG_COLOR = getCssColor('--background'); + const CANVAS_BG = getCssColor('--canvas-background'); + const AXES_COLOR = getCssColor('--canvas-axes'); + const GRID_COLOR = getCssColor('--canvas-grid'); + const BLOCK_COLOR = getCssColor('--canvas-block'); + const CUSTOM_BUILD_COLOR = getCssColor('--canvas-custom-build'); + const NOT_CUSTOM_BUILD_COLOR = getCssColor('--canvas-not-custom-build'); + const DEP_LINE_COLOR = getCssColor('--canvas-dep-line'); + const DEP_LINE_HIGHLIGHTED_COLOR = getCssColor('--canvas-dep-line-highlighted'); + const CPU_COLOR = getCssColor('--canvas-cpu'); + + for (let n=0; n unit.duration >= min_time); + + const graph_height = Y_TICK_DIST * units.length; + const {ctx, graph_width, canvas_width, canvas_height, px_per_sec} = draw_graph_axes('pipeline-graph', graph_height); + const container = document.getElementById('pipeline-container'); + container.style.width = canvas_width; + container.style.height = canvas_height; + + // Canvas for hover highlights. This is a separate layer to improve performance. + const linectx = setup_canvas('pipeline-graph-lines', canvas_width, canvas_height); + linectx.clearRect(0, 0, canvas_width, canvas_height); + ctx.strokeStyle = AXES_COLOR; + // Draw Y tick marks. + for (let n=1; n 1 ? `${unit.name} (v${unit.version})${unit.target}` : `${unit.name}${unit.target}`; - const label = `${labelName}: ${unit.duration}s`; - const text_info = ctx.measureText(label); - const label_x = Math.min(x + 5.0, canvas_width - text_info.width - X_LINE); - ctx.fillText(label, label_x, y + BOX_HEIGHT / 2); - draw_dep_lines(ctx, unit.i, false); + if (unit.rmeta_time != null) { + ctx.beginPath(); + ctx.fillStyle = BLOCK_COLOR; + let ctime = unit.duration - unit.rmeta_time; + roundedRect(ctx, rmeta_x, y, px_per_sec * ctime, BOX_HEIGHT, RADIUS); + ctx.fill(); + } + ctx.fillStyle = TEXT_COLOR; + ctx.textAlign = 'start'; + ctx.textBaseline = 'middle'; + ctx.font = '14px sans-serif'; + + const labelName = (unitCount.get(unit.name) || 0) > 1 ? `${unit.name} (v${unit.version})${unit.target}` : `${unit.name}${unit.target}`; + const label = `${labelName}: ${unit.duration}s`; + + const text_info = ctx.measureText(label); + const label_x = Math.min(x + 5.0, canvas_width - text_info.width - X_LINE); + ctx.fillText(label, label_x, y + BOX_HEIGHT / 2); + draw_dep_lines(ctx, unit.i, false); + } + ctx.restore(); } - ctx.restore(); -} -// Draws lines from the given unit to the units it unlocks. -function draw_dep_lines(ctx, unit_idx, highlighted) { - const unit = UNIT_DATA[unit_idx]; - const {x, y, rmeta_x} = UNIT_COORDS[unit_idx]; - ctx.save(); - for (const unlocked of unit.unlocked_units) { - draw_one_dep_line(ctx, x, y, unlocked, highlighted); - } - for (const unlocked of unit.unlocked_rmeta_units) { - draw_one_dep_line(ctx, rmeta_x, y, unlocked, highlighted); + // Draws lines from the given unit to the units it unlocks. + function draw_dep_lines(ctx, unit_idx, highlighted) { + const unit = UNIT_DATA[unit_idx]; + const {x, y, rmeta_x} = UNIT_COORDS[unit_idx]; + ctx.save(); + for (const unlocked of unit.unlocked_units) { + draw_one_dep_line(ctx, x, y, unlocked, highlighted); + } + for (const unlocked of unit.unlocked_rmeta_units) { + draw_one_dep_line(ctx, rmeta_x, y, unlocked, highlighted); + } + ctx.restore(); } - ctx.restore(); -} -function draw_one_dep_line(ctx, from_x, from_y, to_unit, highlighted) { - if (to_unit in UNIT_COORDS) { - let {x: u_x, y: u_y} = UNIT_COORDS[to_unit]; - ctx.strokeStyle = highlighted ? DEP_LINE_HIGHLIGHTED_COLOR: DEP_LINE_COLOR; - ctx.setLineDash([2]); - ctx.beginPath(); - ctx.moveTo(from_x, from_y+BOX_HEIGHT/2); - ctx.lineTo(from_x-5, from_y+BOX_HEIGHT/2); - ctx.lineTo(from_x-5, u_y+BOX_HEIGHT/2); - ctx.lineTo(u_x, u_y+BOX_HEIGHT/2); - ctx.stroke(); + function draw_one_dep_line(ctx, from_x, from_y, to_unit, highlighted) { + if (to_unit in UNIT_COORDS) { + let {x: u_x, y: u_y} = UNIT_COORDS[to_unit]; + ctx.strokeStyle = highlighted ? DEP_LINE_HIGHLIGHTED_COLOR: DEP_LINE_COLOR; + ctx.setLineDash([2]); + ctx.beginPath(); + ctx.moveTo(from_x, from_y+BOX_HEIGHT/2); + ctx.lineTo(from_x-5, from_y+BOX_HEIGHT/2); + ctx.lineTo(from_x-5, u_y+BOX_HEIGHT/2); + ctx.lineTo(u_x, u_y+BOX_HEIGHT/2); + ctx.stroke(); + } } -} -function render_timing_graph() { - if (CONCURRENCY_DATA.length == 0) { - return; - } - const HEIGHT = 400; - const AXIS_HEIGHT = HEIGHT - MARGIN - Y_LINE; - const TOP_MARGIN = 10; - const GRAPH_HEIGHT = AXIS_HEIGHT - TOP_MARGIN; + function render_timing_graph() { + if (CONCURRENCY_DATA.length == 0) { + return; + } + const HEIGHT = 400; + const AXIS_HEIGHT = HEIGHT - MARGIN - Y_LINE; + const TOP_MARGIN = 10; + const GRAPH_HEIGHT = AXIS_HEIGHT - TOP_MARGIN; - const {canvas_width, graph_width, ctx} = draw_graph_axes('timing-graph', AXIS_HEIGHT); + const {canvas_width, graph_width, ctx} = draw_graph_axes('timing-graph', AXIS_HEIGHT); - // Draw Y tick marks and labels. - let max_v = 0; - for (c of CONCURRENCY_DATA) { - max_v = Math.max(max_v, c.active, c.waiting, c.inactive); - } - const px_per_v = GRAPH_HEIGHT / max_v; - const {step, tick_dist, num_ticks} = split_ticks(max_v, px_per_v, GRAPH_HEIGHT); - ctx.textAlign = 'end'; - for (n=0; n 1) { - ctx.beginPath(); - ctx.fillStyle = cpuFillStyle; - let bottomLeft = coord(CPU_USAGE[0][0], 0); - ctx.moveTo(bottomLeft.x, bottomLeft.y); - for (let i=0; i < CPU_USAGE.length; i++) { - let [time, usage] = CPU_USAGE[i]; - let {x, y} = coord(time, usage / 100.0 * max_v); - ctx.lineTo(x, y); + const cpuFillStyle = CPU_COLOR; + if (CPU_USAGE.length > 1) { + ctx.beginPath(); + ctx.fillStyle = cpuFillStyle; + let bottomLeft = coord(CPU_USAGE[0][0], 0); + ctx.moveTo(bottomLeft.x, bottomLeft.y); + for (let i=0; i < CPU_USAGE.length; i++) { + let [time, usage] = CPU_USAGE[i]; + let {x, y} = coord(time, usage / 100.0 * max_v); + ctx.lineTo(x, y); + } + let bottomRight = coord(CPU_USAGE[CPU_USAGE.length - 1][0], 0); + ctx.lineTo(bottomRight.x, bottomRight.y); + ctx.fill(); } - let bottomRight = coord(CPU_USAGE[CPU_USAGE.length - 1][0], 0); - ctx.lineTo(bottomRight.x, bottomRight.y); - ctx.fill(); - } - function draw_line(style, key) { - let first = CONCURRENCY_DATA[0]; - let last = coord(first.t, key(first)); - ctx.strokeStyle = style; - ctx.beginPath(); - ctx.moveTo(last.x, last.y); - for (let i=1; i 100) { - throw Error("tick loop too long"); - } - count += 1; - if (max_value <= max_ticks * step) { - break; + + // Determine the spacing and number of ticks along an axis. + function split_ticks(max_value, px_per_v, max_px) { + const max_ticks = Math.floor(max_px / MIN_TICK_DIST); + if (max_ticks <= 1) { + // Graph is too small for even 1 tick. + return {step: max_value, tick_dist: max_px, num_ticks: 1}; + } + let step; + if (max_value <= max_ticks) { + step = 1; + } else if (max_value <= max_ticks * 2) { + step = 2; + } else if (max_value <= max_ticks * 4) { + step = 4; + } else if (max_value <= max_ticks * 5) { + step = 5; + } else { + step = 10; + let count = 0; + while (true) { + if (count > 100) { + throw Error("tick loop too long"); + } + count += 1; + if (max_value <= max_ticks * step) { + break; + } + step += 10; } - step += 10; } + const tick_dist = px_per_v * step; + const num_ticks = Math.floor(max_value / step); + return {step, tick_dist, num_ticks}; } - const tick_dist = px_per_v * step; - const num_ticks = Math.floor(max_value / step); - return {step, tick_dist, num_ticks}; -} -function codegen_time(unit) { - if (unit.rmeta_time == null) { - return null; + function codegen_time(unit) { + if (unit.rmeta_time == null) { + return null; + } + let ctime = unit.duration - unit.rmeta_time; + return [unit.rmeta_time, ctime]; } - let ctime = unit.duration - unit.rmeta_time; - return [unit.rmeta_time, ctime]; -} -function roundedRect(ctx, x, y, width, height, r) { - r = Math.min(r, width, height); - ctx.beginPath(); - ctx.moveTo(x+r, y); - ctx.lineTo(x+width-r, y); - ctx.arc(x+width-r, y+r, r, 3*Math.PI/2, 0); - ctx.lineTo(x+width, y+height-r); - ctx.arc(x+width-r, y+height-r, r, 0, Math.PI/2); - ctx.lineTo(x+r, y+height); - ctx.arc(x+r, y+height-r, r, Math.PI/2, Math.PI); - ctx.lineTo(x, y-r); - ctx.arc(x+r, y+r, r, Math.PI, 3*Math.PI/2); - ctx.closePath(); -} + function roundedRect(ctx, x, y, width, height, r) { + r = Math.min(r, width, height); + ctx.beginPath(); + ctx.moveTo(x+r, y); + ctx.lineTo(x+width-r, y); + ctx.arc(x+width-r, y+r, r, 3*Math.PI/2, 0); + ctx.lineTo(x+width, y+height-r); + ctx.arc(x+width-r, y+height-r, r, 0, Math.PI/2); + ctx.lineTo(x+r, y+height); + ctx.arc(x+r, y+height-r, r, Math.PI/2, Math.PI); + ctx.lineTo(x, y-r); + ctx.arc(x+r, y+r, r, Math.PI, 3*Math.PI/2); + ctx.closePath(); + } -function pipeline_mouse_hit(event) { - // This brute-force method can be optimized if needed. - for (let box of HIT_BOXES) { - if (event.offsetX >= box.x && event.offsetX <= box.x2 && - event.offsetY >= box.y && event.offsetY <= box.y2) { - return box; + function pipeline_mouse_hit(event) { + // This brute-force method can be optimized if needed. + for (let box of HIT_BOXES) { + if (event.offsetX >= box.x && event.offsetX <= box.x2 && + event.offsetY >= box.y && event.offsetY <= box.y2) { + return box; + } } } -} -function pipeline_mousemove(event) { - // Highlight dependency lines on mouse hover. - let box = pipeline_mouse_hit(event); - if (box) { - if (box.i != LAST_HOVER) { - LAST_HOVER = box.i; - let g = document.getElementById('pipeline-graph-lines'); - let ctx = g.getContext('2d'); - ctx.clearRect(0, 0, g.width, g.height); - ctx.save(); - ctx.translate(X_LINE, MARGIN); - ctx.lineWidth = 2; - draw_dep_lines(ctx, box.i, true); - - if (box.i in REVERSE_UNIT_DEPS) { - const dep_unit = REVERSE_UNIT_DEPS[box.i]; - if (dep_unit in UNIT_COORDS) { - const {x, y, rmeta_x} = UNIT_COORDS[dep_unit]; - draw_one_dep_line(ctx, x, y, box.i, true); + function pipeline_mousemove(event) { + // Highlight dependency lines on mouse hover. + let box = pipeline_mouse_hit(event); + if (box) { + if (box.i != LAST_HOVER) { + LAST_HOVER = box.i; + let g = document.getElementById('pipeline-graph-lines'); + let ctx = g.getContext('2d'); + ctx.clearRect(0, 0, g.width, g.height); + ctx.save(); + ctx.translate(X_LINE, MARGIN); + ctx.lineWidth = 2; + draw_dep_lines(ctx, box.i, true); + + if (box.i in REVERSE_UNIT_DEPS) { + const dep_unit = REVERSE_UNIT_DEPS[box.i]; + if (dep_unit in UNIT_COORDS) { + const {x, y, rmeta_x} = UNIT_COORDS[dep_unit]; + draw_one_dep_line(ctx, x, y, box.i, true); + } } - } - if (box.i in REVERSE_UNIT_RMETA_DEPS) { - const dep_unit = REVERSE_UNIT_RMETA_DEPS[box.i]; - if (dep_unit in UNIT_COORDS) { - const {x, y, rmeta_x} = UNIT_COORDS[dep_unit]; - draw_one_dep_line(ctx, rmeta_x, y, box.i, true); + if (box.i in REVERSE_UNIT_RMETA_DEPS) { + const dep_unit = REVERSE_UNIT_RMETA_DEPS[box.i]; + if (dep_unit in UNIT_COORDS) { + const {x, y, rmeta_x} = UNIT_COORDS[dep_unit]; + draw_one_dep_line(ctx, rmeta_x, y, box.i, true); + } } + ctx.restore(); } - ctx.restore(); } } -} -render_pipeline_graph(); -render_timing_graph(); + render_pipeline_graph(); + render_timing_graph(); -// Set up and handle controls. -{ - const range = document.getElementById('min-unit-time'); - const time_output = document.getElementById('min-unit-time-output'); - time_output.innerHTML = `${range.value}s`; - range.oninput = event => { + // Set up and handle controls. + { + const range = document.getElementById('min-unit-time'); + const time_output = document.getElementById('min-unit-time-output'); time_output.innerHTML = `${range.value}s`; - render_pipeline_graph(); - }; + range.oninput = event => { + time_output.innerHTML = `${range.value}s`; + render_pipeline_graph(); + }; - const scale = document.getElementById('scale'); - const scale_output = document.getElementById('scale-output'); - scale_output.innerHTML = `${scale.value}`; - scale.oninput = event => { + const scale = document.getElementById('scale'); + const scale_output = document.getElementById('scale-output'); scale_output.innerHTML = `${scale.value}`; - render_pipeline_graph(); - render_timing_graph(); - }; + scale.oninput = event => { + scale_output.innerHTML = `${scale.value}`; + render_pipeline_graph(); + render_timing_graph(); + }; + } +} + +function isDarkmode() { + const customMode = localStorage.getItem("dark-mode"); + if (customMode) { + return customMode === 'dark'; + } + return window.matchMedia("(prefers-color-scheme: dark)").matches; +} + +function enableDarkmode() { + localStorage.setItem('dark-mode', 'dark'); + document.body.classList.add('dark-mode'); + document.body.classList.remove('light-mode'); + render(); } + +function disableDarkmode() { + localStorage.setItem("dark-mode", 'light'); + document.body.classList.remove('dark-mode'); + document.body.classList.add('light-mode'); + render(); +} + +function toggle() { + isDarkmode() ? disableDarkmode() : enableDarkmode(); +} + +if (isDarkmode()) { + enableDarkmode(); +}else{ + disableDarkmode(); +} + +document.getElementById('mode-toggle').addEventListener('click', toggle); diff --git a/src/cargo/core/compiler/timings.rs b/src/cargo/core/compiler/timings.rs index 93506d5c8c9..4d65f1d2f2d 100644 --- a/src/cargo/core/compiler/timings.rs +++ b/src/cargo/core/compiler/timings.rs @@ -603,13 +603,13 @@ fn render_rustc_info(bcx: &BuildContext<'_, '_>) -> String { ) } -static HTML_TMPL: &str = r#" +static HTML_TMPL: &str = r##" Cargo Build Timings — {ROOTS}