summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/charts.c230
-rw-r--r--src/vcr.c143
2 files changed, 294 insertions, 79 deletions
diff --git a/src/charts.c b/src/charts.c
index aeacb18..9daa1b5 100644
--- a/src/charts.c
+++ b/src/charts.c
@@ -84,6 +84,7 @@ typedef enum _vwm_column_type_t {
VWM_COLUMN_PROC_WCHAN,
VWM_COLUMN_PROC_STATE,
VWM_COLUMN_PROC_RSS,
+ VWM_COLUMN_PROC_PGFLT,
VWM_COLUMN_CNT
} vwm_column_type_t;
@@ -99,14 +100,23 @@ typedef enum _vwm_justify_t {
VWM_JUSTIFY_CENTER,
VWM_JUSTIFY_LEFT,
VWM_JUSTIFY_RIGHT,
+ VWM_JUSTIFY_UNIFORM,
VWM_JUSTIFY_CNT
} vwm_justify_t;
+/* extra indentation to apply (added to shift rowsub fields)*/
+typedef enum _vwm_indent_t {
+ VWM_INDENT_NONE,
+ VWM_INDENT_ROWSUB,
+ VWM_INDENT_CNT
+} vwm_indent_t;
+
typedef struct _vwm_column_t {
/* TODO: make the columns configurable and add more description/toggled state here */
unsigned enabled:1;
vwm_column_type_t type;
int width;
+ int last_offset;
} vwm_column_t;
/* a row-column is a row's instance of a column, to facilitate rows that want to reference a column multiple times,
@@ -119,6 +129,7 @@ typedef struct _vwm_row_column_t {
vwm_column_t *column;
vwm_side_t side;
vwm_justify_t justify;
+ vwm_indent_t indent;
} vwm_row_column_t;
/* everything needed by the per-window chart's context */
@@ -145,8 +156,10 @@ typedef struct _vwm_chart_t {
vwm_row_column_t top_row_columns[CHART_MAX_COLUMNS]; /* "top" columns in the chart (vwm logo, hz) */
vwm_row_column_t proc_cpu_row_columns[CHART_MAX_COLUMNS];
vwm_row_column_t proc_mem_row_columns[CHART_MAX_COLUMNS];
+ vwm_row_column_t proc_flt_row_columns[CHART_MAX_COLUMNS];
vwm_row_column_t snowflake_cpu_row_columns[CHART_MAX_COLUMNS]; /* per-proc+thread CPU columns in the snowflaked rows */
vwm_row_column_t snowflake_mem_row_columns[CHART_MAX_COLUMNS]; /* per-proc Memory columns in the snowflaked rows */
+ vwm_row_column_t snowflake_flt_row_columns[CHART_MAX_COLUMNS]; /* per-proc PgFlt columns in the snowflaked rows */
} vwm_chart_t;
/* space we need for every process being monitored */
@@ -156,9 +169,16 @@ typedef struct _vwm_perproc_ctxt_t {
typeof(((vmon_proc_stat_t *)0)->stime) last_stime;
typeof(((vmon_proc_stat_t *)0)->utime) utime_delta;
typeof(((vmon_proc_stat_t *)0)->stime) stime_delta;
+ typeof(((vmon_proc_stat_t *)0)->rss) max_rss;
typeof(((vmon_proc_stat_t *)0)->rss) prev_rss;
typeof(((vmon_proc_stat_t *)0)->rss) rss;
int rss_log2_delta;
+ typeof(((vmon_proc_stat_t *)0)->majflt) prev_majflt;
+ typeof(((vmon_proc_stat_t *)0)->majflt) majflt;
+ int majflt_log2_delta;
+ typeof(((vmon_proc_stat_t *)0)->minflt) prev_minflt;
+ typeof(((vmon_proc_stat_t *)0)->minflt) minflt;
+ int minflt_log2_delta;
int row;
} vwm_perproc_ctxt_t;
@@ -378,6 +398,7 @@ static int count_rows(vmon_proc_t *proc, unsigned no_threads)
if (!proc->is_thread) {
count++; // add the mem row
+ count++; // add the flt row
list_for_each_entry(child, &proc->threads, threads)
count += count_rows(child, no_threads);
}
@@ -468,9 +489,9 @@ static void print_argv(const vwm_charts_t *charts, const vwm_chart_t *chart, int
/* determine if a given process has subsequent siblings in the hierarchy */
-static inline int proc_has_subsequent_siblings(vwm_charts_t *charts, vmon_proc_t *proc)
+static inline int proc_has_subsequent_siblings(const vwm_charts_t *charts, const vmon_proc_t *proc)
{
- struct list_head *sib, *head = &charts->vmon.processes;
+ const struct list_head *sib, *head = &charts->vmon.processes;
if (proc->is_thread) {
if (!charts->no_threads) {
@@ -509,11 +530,31 @@ static unsigned interval_as_hz(vwm_charts_t *charts)
/* draw a process' row slice of a process tree */
-static void draw_tree_row(vwm_charts_t *charts, vwm_chart_t *chart, int x, int depth, int row, const vmon_proc_t *proc, int *res_width)
+static void draw_tree_row(vwm_charts_t *charts, vwm_chart_t *chart, int x, int depth, int row, int rowsub, const vmon_proc_t *proc, int *res_width)
{
int bar_x = 0, bar_y = (row + 1) * VCR_ROW_HEIGHT;
vmon_proc_t *child, *sibling, *last_sibling = NULL;
+ if (rowsub) {
+ /* with the advent of rowsub this does need to hook up the potential tree lines across the top rowsub rows */
+ list_for_each_entry(sibling, &proc->children, siblings) {
+ if (sibling->is_stale)
+ continue;
+
+ if (list_empty(&sibling->children) && (list_empty(&sibling->threads) || charts->no_threads))
+ continue;
+
+ if (proc_has_subsequent_siblings(charts, sibling)) {
+ bar_x = depth * (VCR_ROW_HEIGHT / 2) + 4;
+ vcr_draw_ortho_line(chart->vcr, VCR_LAYER_TEXT,
+ x + bar_x, bar_y - VCR_ROW_HEIGHT, /* dst x1, y1 */
+ x + bar_x, bar_y); /* dst x2, y2 (vertical line) */
+
+ break;
+ }
+ }
+ }
+
/* only if this process isn't the root process @ the window shall we consider all relational drawing conditions */
if (proc == chart->proc)
return;
@@ -593,7 +634,7 @@ static void draw_tree_row(vwm_charts_t *charts, vwm_chart_t *chart, int x, int d
}
/* if we still don't think we need a tee, check if there are threads */
- if (!needs_tee) {
+ if (!needs_tee && !charts->no_threads) {
list_for_each_entry(child, &sibling->threads, threads) {
if (!child->is_stale) {
needs_tee = 1;
@@ -609,18 +650,22 @@ needs_tee:
/* if we're the last sibling, corner the tee by shortening the vbar */
if (proc == last_sibling) {
- vcr_draw_ortho_line(chart->vcr, VCR_LAYER_TEXT,
- x + bar_x, bar_y - VCR_ROW_HEIGHT, /* dst x1, y1 */
- x + bar_x, bar_y - 4); /* dst x2, y2 (vertical bar) */
+ if (!rowsub) {
+ vcr_draw_ortho_line(chart->vcr, VCR_LAYER_TEXT,
+ x + bar_x, bar_y - VCR_ROW_HEIGHT, /* dst x1, y1 */
+ x + bar_x, bar_y - 4); /* dst x2, y2 (vertical bar) */
+ }
} else {
vcr_draw_ortho_line(chart->vcr, VCR_LAYER_TEXT,
x + bar_x, bar_y - VCR_ROW_HEIGHT, /* dst x1, y1 */
x + bar_x, bar_y); /* dst x2, y2 (vertical bar) */
}
- vcr_draw_ortho_line(chart->vcr, VCR_LAYER_TEXT,
- x + bar_x, bar_y - 4, /* dst x1, y1 */
- x + bar_x + 2, bar_y - 4); /* dst x2, y2 (horizontal bar) */
+ if (!rowsub) {
+ vcr_draw_ortho_line(chart->vcr, VCR_LAYER_TEXT,
+ x + bar_x, bar_y - 4, /* dst x1, y1 */
+ x + bar_x + 4, bar_y - 4); /* dst x2, y2 (horizontal bar) */
+ }
/* terminate the outer sibling loop upon drawing the tee... */
break;
@@ -635,7 +680,7 @@ needs_tee:
/* draw a proc row according to the columns configured in columns,
* row==0 is treated specially as the heading row
*/
-static void draw_row_columns(vwm_charts_t *charts, vwm_chart_t *chart, vwm_row_column_t *row_columns, int heading, int depth, int row, const vmon_proc_t *proc)
+static void draw_row_columns(vwm_charts_t *charts, vwm_chart_t *chart, vwm_row_column_t *row_columns, int heading, int depth, int row, int rowsub, const vmon_proc_t *proc)
{
vmon_sys_stat_t *sys_stat = charts->vmon.stores[VMON_STORE_SYS_STAT];
vmon_proc_stat_t *proc_stat = proc->stores[VMON_STORE_PROC_STAT];
@@ -651,6 +696,17 @@ static void draw_row_columns(vwm_charts_t *charts, vwm_chart_t *chart, vwm_row_c
if (!c || !c->enabled)
continue;
+ switch (rc->indent) {
+ case VWM_INDENT_NONE:
+ break;
+ case VWM_INDENT_ROWSUB:
+ if (rowsub)
+ left += 2 * VCR_ROW_HEIGHT;
+ break;
+ default:
+ assert(0);
+ }
+
/* XXX FIXME: i don't constrain columns using a clip mask or restrained drawing, so they can scribble
* on neighboring cells, this is especially problematic with long ARGVs like when compiling.
* As a kludge to work around this for now, clear the column's area immediately before drawing it,
@@ -723,8 +779,15 @@ static void draw_row_columns(vwm_charts_t *charts, vwm_chart_t *chart, vwm_row_c
assert(rc->side == VWM_SIDE_LEFT); /* XXX: technically SIDE_RIGHT could work, but doesn't currently */
- draw_tree_row(charts, chart, left, depth, row, proc, &width);
+ /* draw_tree_row() needs to be augmented to do the right thing in multi-rows; I'm not sure what that means yet.
+ */
+ draw_tree_row(charts, chart, rc->justify == VWM_JUSTIFY_UNIFORM ? c->last_offset : left, depth, row, rowsub, proc, &width);
+ if (rc->justify == VWM_JUSTIFY_UNIFORM)
+ left = c->last_offset;
+
+ c->last_offset = left;
left += width;
+
break;
}
@@ -791,7 +854,22 @@ static void draw_row_columns(vwm_charts_t *charts, vwm_chart_t *chart, vwm_row_c
assert(!proc->is_thread); /* why are we printing RSS for threads? */
- str_len = snpf(str, sizeof(str), "%'u KiB ^", proc_stat->rss * (4096 / 1024));
+ str_len = snpf(str, sizeof(str), "%'llu KiB (%'llu Max)",
+ (unsigned long long)proc_stat->rss * (4096 / 1024),
+ (unsigned long long)proc_ctxt->max_rss * (4096 / 1024));
+
+ break;
+ }
+
+ case VWM_COLUMN_PROC_PGFLT: { /* print the process' page faults */
+ if (heading) /* page faults don't get a heading currently, as it's always below the process row and considered obvious */
+ break;
+
+ assert(!proc->is_thread); /* do page faults get accounted per-thread ? */
+
+ str_len = snpf(str, sizeof(str), "%'llu MajFlts, %'llu MinFlts",
+ (unsigned long long)proc_stat->majflt,
+ (unsigned long long)proc_stat->minflt);
break;
}
@@ -840,11 +918,17 @@ static void draw_row_columns(vwm_charts_t *charts, vwm_chart_t *chart, vwm_row_c
xpos += (c->width - str_width) / 2;
break;
+ case VWM_JUSTIFY_UNIFORM:
+ xpos = c->last_offset;
+ break;
+
default:
assert(0);
}
vcr_draw_text(chart->vcr, VCR_LAYER_TEXT, xpos, row, strs, 1, NULL);
+
+ c->last_offset = xpos;
}
if (advance) {
@@ -924,21 +1008,26 @@ static void draw_overlay_row(vwm_charts_t *charts, vwm_chart_t *chart, vmon_proc
/* skip if obviously unnecessary (this can be further improved, but this makes a big difference as-is) */
if (!deferred_pass && !chart->redraw_needed &&
!columns_changed(charts, chart, chart->proc_cpu_columns, row, proc) &&
- (proc->is_thread || !columns_changed(charts, chart, chart->proc_mem_columns, row + 1, proc)))
+ (proc->is_thread || !columns_changed(charts, chart, chart->proc_mem_columns, row /* FIXME FIXME */, proc)))
return;
if (!proc->is_new) { /* XXX for now always clear the row, this should be capable of being optimized in the future (if the datums driving the text haven't changed...) */
vcr_clear_row(chart->vcr, VCR_LAYER_TEXT, row, -1, -1);
- if (!proc->is_thread)
+ if (!proc->is_thread) {
vcr_clear_row(chart->vcr, VCR_LAYER_TEXT, row + 1, -1, -1);
+ vcr_clear_row(chart->vcr, VCR_LAYER_TEXT, row + 2, -1, -1);
+ }
}
- draw_row_columns(charts, chart, chart->proc_cpu_row_columns, 0 /* heading */, depth, row, proc);
+ draw_row_columns(charts, chart, chart->proc_cpu_row_columns, 0 /* heading */, depth, row, 0, proc);
vcr_shadow_row(chart->vcr, VCR_LAYER_TEXT, row);
if (!proc->is_thread) {
- draw_row_columns(charts, chart, chart->proc_mem_row_columns, 0 /* heading */, depth, row + 1, proc);
+ draw_row_columns(charts, chart, chart->proc_mem_row_columns, 0 /* heading */, depth, row + 1, 1, proc);
vcr_shadow_row(chart->vcr, VCR_LAYER_TEXT, row + 1);
+
+ draw_row_columns(charts, chart, chart->proc_flt_row_columns, 0 /* heading */, depth, row + 2, 2, proc);
+ vcr_shadow_row(chart->vcr, VCR_LAYER_TEXT, row + 2);
}
}
@@ -1048,8 +1137,22 @@ static void draw_chart_rest(vwm_charts_t *charts, vwm_chart_t *chart, vmon_proc_
snowflake_row(charts, chart, (*row));
chart->snowflakes_cnt++;
+ /* stamp the final pgflts (and whatever else we include) into chart.text_picture */
+ draw_row_columns(charts, chart, chart->snowflake_flt_row_columns, 0 /* heading */, 0 /* depth */, chart->hierarchy_end, 2, proc);
+ vcr_shadow_row(chart->vcr, VCR_LAYER_TEXT, chart->hierarchy_end);
+
+ chart->hierarchy_end--;
+ (*row)--;
+
+
+
+ mark_finish(charts, chart, (*row));
+ /* extract the row from the various layers */
+ snowflake_row(charts, chart, (*row));
+ chart->snowflakes_cnt++;
+
/* stamp the final RSS (and whatever else we include) into chart.text_picture */
- draw_row_columns(charts, chart, chart->snowflake_mem_row_columns, 0 /* heading */, 0 /* depth */, chart->hierarchy_end, proc);
+ draw_row_columns(charts, chart, chart->snowflake_mem_row_columns, 0 /* heading */, 0 /* depth */, chart->hierarchy_end, 1, proc);
vcr_shadow_row(chart->vcr, VCR_LAYER_TEXT, chart->hierarchy_end);
chart->hierarchy_end--;
@@ -1063,7 +1166,7 @@ static void draw_chart_rest(vwm_charts_t *charts, vwm_chart_t *chart, vmon_proc_
chart->snowflakes_cnt++;
/* stamp the name (and whatever else we include) into chart.text_picture */
- draw_row_columns(charts, chart, chart->snowflake_cpu_row_columns, 0 /* heading */, 0 /* depth */, chart->hierarchy_end, proc);
+ draw_row_columns(charts, chart, chart->snowflake_cpu_row_columns, 0 /* heading */, 0 /* depth */, chart->hierarchy_end, 0, proc);
vcr_shadow_row(chart->vcr, VCR_LAYER_TEXT, chart->hierarchy_end);
chart->hierarchy_end--;
@@ -1089,7 +1192,9 @@ static void draw_chart_rest(vwm_charts_t *charts, vwm_chart_t *chart, vmon_proc_
proc_ctxt->last_utime = proc_stat->utime;
proc_ctxt->last_stime = proc_stat->stime;
- /* TODO: this should probably be skipped if proc->is_thread? */
+ /* TODO: this rss stuff should probably be skipped if proc->is_thread? */
+ if (proc_stat->rss > proc_ctxt->max_rss)
+ proc_ctxt->max_rss = proc_stat->rss;
proc_ctxt->prev_rss = proc_ctxt->rss;
proc_ctxt->rss = proc_stat->rss;
if (proc_ctxt->rss > proc_ctxt->prev_rss) {
@@ -1098,6 +1203,20 @@ static void draw_chart_rest(vwm_charts_t *charts, vwm_chart_t *chart, vmon_proc_
proc_ctxt->rss_log2_delta = -(int)ilog2_ish(proc_ctxt->prev_rss - proc_ctxt->rss);
}
+ proc_ctxt->prev_minflt = proc_ctxt->minflt;
+ proc_ctxt->minflt = proc_stat->minflt;
+ if (proc_ctxt->minflt > proc_ctxt->prev_minflt)
+ proc_ctxt->minflt_log2_delta = ilog2_ish(proc_ctxt->minflt - proc_ctxt->prev_minflt);
+ else
+ proc_ctxt->minflt_log2_delta = 0;
+
+ proc_ctxt->prev_majflt = proc_ctxt->majflt;
+ proc_ctxt->majflt = proc_stat->majflt;
+ if (proc_ctxt->majflt > proc_ctxt->prev_majflt)
+ proc_ctxt->majflt_log2_delta = ilog2_ish(proc_ctxt->majflt - proc_ctxt->prev_majflt);
+ else
+ proc_ctxt->majflt_log2_delta = 0;
+
proc_ctxt->generation = charts->vmon.generation;
}
}
@@ -1138,6 +1257,10 @@ static void draw_chart_rest(vwm_charts_t *charts, vwm_chart_t *chart, vmon_proc_
allocate_row(charts, chart, (*row) + 1);
vcr_set_row_palette(chart->vcr, (*row) + 1, VCR_ROW_PALETTE_1);
chart->hierarchy_end++;
+
+ allocate_row(charts, chart, (*row) + 2);
+ vcr_set_row_palette(chart->vcr, (*row) + 2, VCR_ROW_PALETTE_2);
+ chart->hierarchy_end++;
}
/* we need a minimum of two samples before we can compute a delta to plot,
@@ -1167,17 +1290,46 @@ static void draw_chart_rest(vwm_charts_t *charts, vwm_chart_t *chart, vmon_proc_
1.f,
1.f,
VCR_LAYER_GRAPHA);
- } else if (proc_ctxt->rss != proc_ctxt->prev_rss) {
- // fprintf(stderr, "row=%i rss_delta=%i rss=%llu\n", (*row) + 1, proc_ctxt->rss_log2_delta, proc_ctxt->rss);
- draw_bars(charts, chart, *row + 1,
+ draw_bars(charts, chart, *row + 2,
1.f /* mult */,
- proc_ctxt->rss_log2_delta < 0 ? -proc_ctxt->rss_log2_delta : 0.f,
- 1.f / VCR_ROW_HEIGHT,
+ 1.f,
+ 1.f,
VCR_LAYER_GRAPHB,
- proc_ctxt->rss_log2_delta > 0 ? proc_ctxt->rss_log2_delta : 0.f,
- 1.f / VCR_ROW_HEIGHT,
+ 1.f,
+ 1.f,
VCR_LAYER_GRAPHA);
+ } else {
+ if (proc_ctxt->rss != proc_ctxt->prev_rss) {
+ // fprintf(stderr, "row=%i rss_delta=%i rss=%llu\n", (*row) + 1, proc_ctxt->rss_log2_delta, proc_ctxt->rss);
+ draw_bars(charts, chart, *row + 1,
+ 1.f /* mult */,
+ proc_ctxt->rss_log2_delta < 0 ? -proc_ctxt->rss_log2_delta : 0.f,
+ 1.f / VCR_ROW_HEIGHT,
+ VCR_LAYER_GRAPHB,
+ proc_ctxt->rss_log2_delta > 0 ? proc_ctxt->rss_log2_delta : 0.f,
+ 1.f / VCR_ROW_HEIGHT,
+ VCR_LAYER_GRAPHA);
+ }
+
+ if (proc_ctxt->majflt != proc_ctxt->prev_majflt ||
+ proc_ctxt->minflt != proc_ctxt->prev_minflt) {
+ // fprintf(stderr, "row=%i rss_delta=%i rss=%llu\n", (*row) + 1, proc_ctxt->rss_log2_delta, proc_ctxt->rss);
+ draw_bars(charts, chart, *row + 2,
+ 1.f /* mult */,
+ proc_ctxt->majflt_log2_delta > 0 ? proc_ctxt->majflt_log2_delta : 0.f,
+ 1.f / VCR_ROW_HEIGHT,
+ VCR_LAYER_GRAPHB,
+ proc_ctxt->minflt_log2_delta > 0 ? proc_ctxt->minflt_log2_delta : 0.f,
+ 1.f / VCR_ROW_HEIGHT,
+ VCR_LAYER_GRAPHA);
+ }
}
+ /* TODO TODO TODO */
+ /* TODO TODO TODO */
+ /* TODO TODO TODO */
+//#error "pagfaults"
+ /* TODO TODO TODO */
+ /* TODO TODO TODO */
}
}
@@ -1187,8 +1339,10 @@ static void draw_chart_rest(vwm_charts_t *charts, vwm_chart_t *chart, vmon_proc_
/* note these are suppressed for --no-threads */
(*row)++;
- if (!proc->is_thread)
+ if (!proc->is_thread) {
(*row)++; /* per-proc RSS row */
+ (*row)++; /* per-proc flts row */
+ }
(*depth)++;
}
@@ -1248,13 +1402,13 @@ static void draw_chart(vwm_charts_t *charts, vwm_chart_t *chart, vmon_proc_t *pr
if (sample_duration_idx == (charts->this_sample_duration - 1)) {
if (deferred_pass || (!charts->defer_maintenance && (chart->redraw_needed || charts->prev_sampling_interval_secs != charts->sampling_interval_secs))) {
vcr_clear_row(chart->vcr, VCR_LAYER_TEXT, row, -1, -1);
- draw_row_columns(charts, chart, chart->top_row_columns, 1 /* heading */, 0 /* depth */, row, proc);
+ draw_row_columns(charts, chart, chart->top_row_columns, 1 /* heading */, 0 /* depth */, row, 0, proc);
vcr_shadow_row(chart->vcr, VCR_LAYER_TEXT, row);
/* XXX: note at this time there's no overlay text for the IRQ/SoftIRQ (row + 1) (which should probably change) */
vcr_clear_row(chart->vcr, VCR_LAYER_TEXT, row + 1, -1, -1);
- draw_row_columns(charts, chart, chart->proc_cpu_row_columns, 1 /* heading */, 0 /* depth */, row + 2, proc);
+ draw_row_columns(charts, chart, chart->proc_cpu_row_columns, 1 /* heading */, 0 /* depth */, row + 2, 0, proc);
vcr_shadow_row(chart->vcr, VCR_LAYER_TEXT, row + 1);
}
@@ -1400,6 +1554,7 @@ vwm_chart_t * vwm_chart_create(vwm_charts_t *charts, int pid, int width, int hei
chart->proc_mem_columns[0] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_ROW };
chart->proc_mem_columns[1] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_RSS };
+ chart->proc_mem_columns[2] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_PGFLT };
chart->snowflake_cpu_columns[0] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_PID };
chart->snowflake_cpu_columns[1] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_USER };
@@ -1408,6 +1563,7 @@ vwm_chart_t * vwm_chart_create(vwm_charts_t *charts, int pid, int width, int hei
chart->snowflake_cpu_columns[4] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_ARGV };
chart->snowflake_mem_columns[0] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_RSS };
+ chart->snowflake_mem_columns[1] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_PGFLT };
chart->top_row_columns[0] = (vwm_row_column_t){ .column = &chart->top_columns[0], .side = VWM_SIDE_RIGHT, .justify = VWM_JUSTIFY_RIGHT };
@@ -1424,8 +1580,14 @@ vwm_chart_t * vwm_chart_create(vwm_charts_t *charts, int pid, int width, int hei
chart->proc_cpu_row_columns[9] = (vwm_row_column_t){ .column = &chart->proc_cpu_columns[8], .side = VWM_SIDE_RIGHT, .justify = VWM_JUSTIFY_RIGHT };
chart->proc_mem_row_columns[0] = (vwm_row_column_t){ .column = &chart->proc_mem_columns[0], .side = VWM_SIDE_LEFT, .justify = VWM_JUSTIFY_LEFT };
- chart->proc_mem_row_columns[1] = (vwm_row_column_t){ .column = &chart->proc_cpu_columns[0], .side = VWM_SIDE_RIGHT, .justify = VWM_JUSTIFY_RIGHT };
- chart->proc_mem_row_columns[2] = (vwm_row_column_t){ .column = &chart->proc_mem_columns[1], .side = VWM_SIDE_RIGHT, .justify = VWM_JUSTIFY_RIGHT };
+ chart->proc_mem_row_columns[1] = (vwm_row_column_t){ .column = &chart->proc_cpu_columns[4], .side = VWM_SIDE_LEFT, .justify = VWM_JUSTIFY_UNIFORM };
+ chart->proc_mem_row_columns[2] = (vwm_row_column_t){ .column = &chart->proc_mem_columns[1], .side = VWM_SIDE_LEFT, .justify = VWM_JUSTIFY_LEFT, .indent = VWM_INDENT_ROWSUB };
+ chart->proc_mem_row_columns[3] = (vwm_row_column_t){ .column = &chart->proc_mem_columns[0], .side = VWM_SIDE_RIGHT, .justify = VWM_JUSTIFY_RIGHT };
+
+ chart->proc_flt_row_columns[0] = (vwm_row_column_t){ .column = &chart->proc_mem_columns[0], .side = VWM_SIDE_LEFT, .justify = VWM_JUSTIFY_LEFT };
+ chart->proc_flt_row_columns[1] = (vwm_row_column_t){ .column = &chart->proc_cpu_columns[4], .side = VWM_SIDE_LEFT, .justify = VWM_JUSTIFY_UNIFORM };
+ chart->proc_flt_row_columns[2] = (vwm_row_column_t){ .column = &chart->proc_mem_columns[2], .side = VWM_SIDE_LEFT, .justify = VWM_JUSTIFY_LEFT, .indent = VWM_INDENT_ROWSUB };
+ chart->proc_flt_row_columns[3] = (vwm_row_column_t){ .column = &chart->proc_mem_columns[0], .side = VWM_SIDE_RIGHT, .justify = VWM_JUSTIFY_RIGHT };
chart->snowflake_cpu_row_columns[0] = (vwm_row_column_t){ .column = &chart->snowflake_cpu_columns[0], .side = VWM_SIDE_LEFT, .justify = VWM_JUSTIFY_RIGHT };
chart->snowflake_cpu_row_columns[1] = (vwm_row_column_t){ .column = &chart->snowflake_cpu_columns[1], .side = VWM_SIDE_LEFT, .justify = VWM_JUSTIFY_RIGHT };
@@ -1433,7 +1595,9 @@ vwm_chart_t * vwm_chart_create(vwm_charts_t *charts, int pid, int width, int hei
chart->snowflake_cpu_row_columns[3] = (vwm_row_column_t){ .column = &chart->snowflake_cpu_columns[3], .side = VWM_SIDE_LEFT, .justify = VWM_JUSTIFY_RIGHT };
chart->snowflake_cpu_row_columns[4] = (vwm_row_column_t){ .column = &chart->snowflake_cpu_columns[4], .side = VWM_SIDE_LEFT, .justify = VWM_JUSTIFY_LEFT };
- chart->snowflake_mem_row_columns[0] = (vwm_row_column_t){ .column = &chart->snowflake_mem_columns[0], .side = VWM_SIDE_LEFT, .justify = VWM_JUSTIFY_RIGHT };
+ chart->snowflake_mem_row_columns[0] = (vwm_row_column_t){ .column = &chart->snowflake_mem_columns[0], .side = VWM_SIDE_LEFT, .justify = VWM_JUSTIFY_LEFT, .indent = VWM_INDENT_ROWSUB };
+
+ chart->snowflake_flt_row_columns[0] = (vwm_row_column_t){ .column = &chart->snowflake_mem_columns[1], .side = VWM_SIDE_LEFT, .justify = VWM_JUSTIFY_LEFT, .indent = VWM_INDENT_ROWSUB };
/* add the client process to the monitoring hierarchy */
/* XXX note libvmon here maintains a unique callback for each unique callback+xwin pair, so multi-window processes work */
diff --git a/src/vcr.c b/src/vcr.c
index c9a7c6f..7e6b77b 100644
--- a/src/vcr.c
+++ b/src/vcr.c
@@ -104,8 +104,6 @@ typedef struct vcr_backend_t {
text_fill,
bg_fill,
snowflakes_text_fill,
- grapha_fill,
- graphb_fill,
finish_fill;
} xlib;
#endif /* USE_XLIB */
@@ -148,10 +146,14 @@ typedef struct vcr_t {
Pixmap text_pixmap; /* pixmap for charted text (kept around for XDrawText usage) */
Picture text_picture; /* picture representation of text_pixmap */
Picture shadow_picture; /* text shadow layer */
+#if 0
Picture grapha_picture; /* graph A layer */
Picture graphb_picture; /* graph B layer */
Picture tmp_a_picture; /* 1 row worth of temporary graph A space */
Picture tmp_b_picture; /* 1 row worth of temporary graph B space */
+#endif
+ Picture graphs_picture; /* ARGB graphs layer */
+ Picture tmp_row_picture;/* 1 row worth of temporary ARGB graphs space */
Picture picture; /* chart picture derived from the pixmap, for render compositing */
} xlib;
#endif /* USE_XLIB */
@@ -213,9 +215,9 @@ typedef struct vcr_dest_t {
} vcr_dest_t;
-#ifdef USE_XLIB
#define CHART_GRAPH_MIN_WIDTH 200 /* always create graphs at least this large */
#define CHART_GRAPH_MIN_HEIGHT (4 * VCR_ROW_HEIGHT)
+#ifdef USE_XLIB
#define CHART_MASK_DEPTH 8 /* XXX: 1 would save memory, but Xorg isn't good at it */
#define CHART_FIXED_FONT "-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso10646-1"
@@ -225,8 +227,18 @@ static XRenderColor chart_visible_color = { 0xffff, 0xffff, 0xffff, 0xffff },
chart_div_color = { 0x2000, 0x3000, 0x2000, 0x9000},
chart_snowflakes_visible_color = { 0xd000, 0xd000, 0xd000, 0x8000 },
chart_trans_color = {0x00, 0x00, 0x00, 0x00},
- chart_grapha_color = { 0xff00, 0x0000, 0x0000, 0x3000 }, /* ~red */
- chart_graphb_color = { 0x0000, 0xffff, 0xffff, 0x3000 }; /* ~cyan */
+ chart_graph_palette[VCR_ROW_PALETTE_CNT][2] = {
+ {
+ { 0xff00, 0x0000, 0x0000, 0x3000 }, /* ~red */
+ { 0x0000, 0xffff, 0xffff, 0x3000 }, /* ~cyan */
+ }, {
+ { 0xff00, 0x0000, 0xffff, 0x3000 }, /* ~magenta */
+ { 0x0000, 0xffff, 0x0000, 0x3000 }, /* ~green */
+ }, {
+ { 0x4000, 0x6000, 0xffff, 0x3000 }, /* ~blue */
+ { 0xff00, 0xa500, 0x0000, 0x3000 }, /* ~orange */
+ }
+ };
static XRenderPictureAttributes pa_repeat = { .repeat = 1 };
static XRenderPictureAttributes pa_no_repeat = { .repeat = 0 };
@@ -345,8 +357,6 @@ static vcr_backend_t * vcr_backend_xlib_setup(vcr_backend_t *vbe, vwm_xserver_t
XRenderFillRectangle(xserver->display, PictOpSrc, vbe->xlib.bg_fill, &chart_div_color, 0, VCR_ROW_HEIGHT - 1, 1, 1);
vbe->xlib.snowflakes_text_fill = create_picture_fill(xserver, 1, 1, 32, CPRepeat, &pa_repeat, &chart_snowflakes_visible_color, NULL);
- vbe->xlib.grapha_fill = create_picture_fill(xserver, 1, 1, 32, CPRepeat, &pa_repeat, &chart_grapha_color, NULL);
- vbe->xlib.graphb_fill = create_picture_fill(xserver, 1, 1, 32, CPRepeat, &pa_repeat, &chart_graphb_color, NULL);
vbe->xlib.finish_fill = create_picture(xserver, 1, 2, 32, CPRepeat, &pa_repeat, NULL);
XRenderFillRectangle(xserver->display, PictOpSrc, vbe->xlib.finish_fill, &chart_visible_color, 0, 0, 1, 1);
@@ -524,8 +534,7 @@ vcr_backend_t * vcr_backend_free(vcr_backend_t *vbe)
XRenderFreePicture(vbe->xlib.xserver->display, vbe->xlib.text_fill);
XRenderFreePicture(vbe->xlib.xserver->display, vbe->xlib.bg_fill);
XRenderFreePicture(vbe->xlib.xserver->display, vbe->xlib.snowflakes_text_fill);
- XRenderFreePicture(vbe->xlib.xserver->display, vbe->xlib.grapha_fill);
- XRenderFreePicture(vbe->xlib.xserver->display, vbe->xlib.graphb_fill);
+
XRenderFreePicture(vbe->xlib.xserver->display, vbe->xlib.finish_fill);
XFreeFont(vbe->xlib.xserver->display, vbe->xlib.chart_font);
XFreeGC(vbe->xlib.xserver->display, vbe->xlib.text_gc);
@@ -745,10 +754,14 @@ static void vcr_free_xlib_internal(vcr_t *vcr)
assert(xserver);
+#if 0
XRenderFreePicture(xserver->display, vcr->xlib.grapha_picture);
XRenderFreePicture(xserver->display, vcr->xlib.graphb_picture);
XRenderFreePicture(xserver->display, vcr->xlib.tmp_a_picture);
XRenderFreePicture(xserver->display, vcr->xlib.tmp_b_picture);
+#endif
+ XRenderFreePicture(xserver->display, vcr->xlib.graphs_picture);
+ XRenderFreePicture(xserver->display, vcr->xlib.tmp_row_picture);
XRenderFreePicture(xserver->display, vcr->xlib.text_picture);
XFreePixmap(xserver->display, vcr->xlib.text_pixmap);
XRenderFreePicture(xserver->display, vcr->xlib.shadow_picture);
@@ -774,6 +787,7 @@ static void vcr_copy_xlib_internal(vcr_t *src, vcr_t *dest)
xserver = src->backend->xlib.xserver;
/* XXX: note the graph pictures are copied from their current phase in the x dimension */
+#if 0
XRenderComposite(xserver->display, PictOpSrc, src->xlib.grapha_picture, None, dest->xlib.grapha_picture,
src->phase, 0, /* src x, y */
0, 0, /* mask x, y */
@@ -784,6 +798,12 @@ static void vcr_copy_xlib_internal(vcr_t *src, vcr_t *dest)
0, 0, /* mask x, y */
dest->phase, 0, /* dest x, y */
src->width, src->height);
+#endif
+ XRenderComposite(xserver->display, PictOpSrc, src->xlib.graphs_picture, None, dest->xlib.graphs_picture,
+ src->phase, 0, /* src x, y */
+ 0, 0, /* mask x, y */
+ dest->phase, 0, /* dest x, y */
+ src->width, src->height);
XRenderComposite(xserver->display, PictOpSrc, src->xlib.text_picture, None, dest->xlib.text_picture,
0, 0, /* src x, y */
0, 0, /* mask x, y */
@@ -839,6 +859,8 @@ vcr_t * vcr_free(vcr_t *vcr)
*/
int vcr_resize_visible(vcr_t *vcr, int width, int height)
{
+ int new_width, new_height;
+
assert(vcr);
assert(vcr->backend);
assert(width > 0);
@@ -862,14 +884,18 @@ int vcr_resize_visible(vcr_t *vcr, int width, int height)
return 1; /* redraw needed */
}
+ new_width = MAX(vcr->width, MAX(width, CHART_GRAPH_MIN_WIDTH));
+ new_height = MAX(vcr->height, MAX(height, CHART_GRAPH_MIN_HEIGHT));
+
{ /* the meta layer isn't backend-specific */
vcr_row_meta_t *old = vcr->meta;
- vcr->meta = calloc(height / VCR_ROW_HEIGHT, sizeof(vcr_row_meta_t));
+ vcr->meta = calloc(new_height / VCR_ROW_HEIGHT, sizeof(vcr_row_meta_t));
if (!vcr->meta)
return -ENOMEM;
if (old) {
+//#error "this isn't really sufficient, if the extant hierarchy was beyond the old meta, copying it doesn't initialize the remainder - we need to get the meta all set for extant rows"
memcpy(vcr->meta, old, (vcr->height / VCR_ROW_HEIGHT) * sizeof(vcr_row_meta_t));
free(old);
}
@@ -884,14 +910,18 @@ int vcr_resize_visible(vcr_t *vcr, int width, int height)
vcr_t existing = *vcr; /* stow the current vcr's contents for copy+free */
vwm_xserver_t *xserver = vcr->backend->xlib.xserver;
- vcr->width = MAX(vcr->width, MAX(width, CHART_GRAPH_MIN_WIDTH));
- vcr->height = MAX(vcr->height, MAX(height, CHART_GRAPH_MIN_HEIGHT));
+ vcr->width = new_width;
+ vcr->height = new_height;
/* XXX: note this is actually _the_ place these things get allocated */
+#if 0
vcr->xlib.grapha_picture = create_picture_fill(xserver, vcr->width, vcr->height, CHART_MASK_DEPTH, CPRepeat, &pa_repeat, &chart_trans_color, NULL);
vcr->xlib.graphb_picture = create_picture_fill(xserver, vcr->width, vcr->height, CHART_MASK_DEPTH, CPRepeat, &pa_repeat, &chart_trans_color, NULL);
vcr->xlib.tmp_a_picture = create_picture(xserver, vcr->width, VCR_ROW_HEIGHT, CHART_MASK_DEPTH, 0, NULL, NULL);
vcr->xlib.tmp_b_picture = create_picture(xserver, vcr->width, VCR_ROW_HEIGHT, CHART_MASK_DEPTH, 0, NULL, NULL);
+#endif
+ vcr->xlib.graphs_picture = create_picture_fill(xserver, vcr->width, vcr->height, 32, CPRepeat, &pa_repeat, &chart_trans_color, NULL);
+ vcr->xlib.tmp_row_picture = create_picture(xserver, vcr->width, VCR_ROW_HEIGHT, 32, 0, NULL, NULL);
/* keep the text_pixmap reference around for XDrawText usage */
vcr->xlib.text_picture = create_picture_fill(xserver, vcr->width, vcr->height, CHART_MASK_DEPTH, 0, NULL, &chart_trans_color, &vcr->xlib.text_pixmap);
@@ -908,7 +938,7 @@ int vcr_resize_visible(vcr_t *vcr, int width, int height)
#endif /* USE_XLIB */
case VCR_BACKEND_TYPE_MEM: {
- int pitch = (width + 1) >> 1;
+ int pitch = (new_width + 1) >> 1;
/* no attempt to preserve the existing contents is done for the mem backend,
* as it's intended for a non-interactive headless use case - there is no
@@ -916,7 +946,7 @@ int vcr_resize_visible(vcr_t *vcr, int width, int height)
* then never recurs.
*/
assert(!vcr->mem.bits); /* since we're assuming this doesn't recur, assert it */
- vcr->mem.bits = calloc(pitch * height, sizeof(uint8_t));
+ vcr->mem.bits = calloc(pitch * new_height, sizeof(uint8_t));
if (!vcr->mem.bits)
return -ENOMEM;
@@ -928,8 +958,8 @@ int vcr_resize_visible(vcr_t *vcr, int width, int height)
}
vcr->mem.pitch = pitch;
- vcr->width = width;
- vcr->height = height;
+ vcr->width = new_width;
+ vcr->height = new_height;
break;
}
@@ -1174,18 +1204,26 @@ void vcr_mark_finish_line(vcr_t *vcr, vcr_layer_t layer, int row)
#ifdef USE_XLIB
case VCR_BACKEND_TYPE_XLIB: {
vwm_xserver_t *xserver = vcr->backend->xlib.xserver;
- Picture dest;
+ Picture dest = vcr->xlib.graphs_picture;
+ /* FIXME: finish_fill basically disregards layers and splats white into the argb picture,
+ * previously that was fine since each layer had its own picture. Now it's a single argb
+ * surface so it should probably be selecting a different filler source based on hte layer,
+ * or it might make more sense to simply get rid of layer-specific finish lines. The finish
+ * line is arguably conceptually all-layers.
+ */
+#if 0
switch (layer) {
case VCR_LAYER_GRAPHA:
- dest = vcr->xlib.grapha_picture;
+ dest = vcr->xlib.graphs_picture;
break;
case VCR_LAYER_GRAPHB:
- dest = vcr->xlib.graphb_picture;
+ dest = vcr->xlib.graphs_picture;
break;
default:
assert(0);
}
+#endif
assert(xserver);
@@ -1247,14 +1285,15 @@ void vcr_draw_bar(vcr_t *vcr, vcr_layer_t layer, vcr_bar_base_t base, int row, i
#ifdef USE_XLIB
case VCR_BACKEND_TYPE_XLIB: {
vwm_xserver_t *xserver = vcr->backend->xlib.xserver;
- Picture *dest;
+ Picture dest = vcr->xlib.graphs_picture;
+ XRenderColor *color;
switch (layer) {
case VCR_LAYER_GRAPHA:
- dest = &vcr->xlib.grapha_picture;
+ color = &chart_graph_palette[vcr->meta[row].palette][0];
break;
case VCR_LAYER_GRAPHB:
- dest = &vcr->xlib.graphb_picture;
+ color = &chart_graph_palette[vcr->meta[row].palette][1];
break;
default:
assert(0);
@@ -1262,7 +1301,7 @@ void vcr_draw_bar(vcr_t *vcr, vcr_layer_t layer, vcr_bar_base_t base, int row, i
assert(xserver);
- XRenderFillRectangle(xserver->display, PictOpSrc, *dest, &chart_visible_color,
+ XRenderFillRectangle(xserver->display, PictOpAdd, dest, color,
vcr->phase, y, /* dst x, y */
1, height); /* dst w, h */
@@ -1325,8 +1364,8 @@ void vcr_clear_row(vcr_t *vcr, vcr_layer_t layer, int row, int x, int width)
Picture *layers[] = { /* vcr->xlib should just have these in an array */
&vcr->xlib.text_picture,
&vcr->xlib.shadow_picture,
- &vcr->xlib.grapha_picture,
- &vcr->xlib.graphb_picture,
+ &vcr->xlib.graphs_picture,
+ &vcr->xlib.graphs_picture,
};
vwm_xserver_t *xserver = vcr->backend->xlib.xserver;
@@ -1403,11 +1442,13 @@ void vcr_shift_below_row_up_one(vcr_t *vcr, int row)
{
vcr_row_meta_t *dest = &vcr->meta[row];
vcr_row_meta_t *src = &vcr->meta[(1 + row)];
- size_t len = ((1 + *(vcr->hierarchy_end_ptr)) - (1 + row)) * sizeof(vcr_row_meta_t);
+ size_t len = ((1 + *(vcr->hierarchy_end_ptr)) - (1 + row));
assert(*(vcr->hierarchy_end_ptr) >= row);
- memmove(dest, src, len);
+ len = MIN(len, (vcr->height / VCR_ROW_HEIGHT) - (1 + row));
+
+ memmove(dest, src, len * sizeof(vcr_row_meta_t));
}
switch (vcr->backend->type) {
@@ -1416,8 +1457,8 @@ void vcr_shift_below_row_up_one(vcr_t *vcr, int row)
Picture *layers[] = { /* vcr->xlib should just have these in an array */
&vcr->xlib.text_picture,
&vcr->xlib.shadow_picture,
- &vcr->xlib.grapha_picture,
- &vcr->xlib.graphb_picture,
+ &vcr->xlib.graphs_picture,
+ &vcr->xlib.graphs_picture,
};
vwm_xserver_t *xserver = vcr->backend->xlib.xserver;
@@ -1493,8 +1534,8 @@ void vcr_shift_below_row_down_one(vcr_t *vcr, int row)
Picture *layers[] = { /* vcr->xlib should just have these in an array */
&vcr->xlib.text_picture,
&vcr->xlib.shadow_picture,
- &vcr->xlib.grapha_picture,
- &vcr->xlib.graphb_picture,
+ &vcr->xlib.graphs_picture,
+ &vcr->xlib.graphs_picture,
};
vwm_xserver_t *xserver = vcr->backend->xlib.xserver;
@@ -1669,12 +1710,12 @@ void vcr_stash_row(vcr_t *vcr, vcr_layer_t layer, int row)
#ifdef USE_XLIB
case VCR_BACKEND_TYPE_XLIB: {
Picture *layers[] = {
- [VCR_LAYER_GRAPHA] = &vcr->xlib.grapha_picture,
- [VCR_LAYER_GRAPHB] = &vcr->xlib.graphb_picture,
+ [VCR_LAYER_GRAPHA] = &vcr->xlib.graphs_picture,
+ [VCR_LAYER_GRAPHB] = &vcr->xlib.graphs_picture,
};
Picture *tmps[] = {
- [VCR_LAYER_GRAPHA] = &vcr->xlib.tmp_a_picture,
- [VCR_LAYER_GRAPHB] = &vcr->xlib.tmp_b_picture,
+ [VCR_LAYER_GRAPHA] = &vcr->xlib.tmp_row_picture,
+ [VCR_LAYER_GRAPHB] = &vcr->xlib.tmp_row_picture,
};
vwm_xserver_t *xserver = vcr->backend->xlib.xserver;
@@ -1732,12 +1773,12 @@ void vcr_unstash_row(vcr_t *vcr, vcr_layer_t layer, int row)
#ifdef USE_XLIB
case VCR_BACKEND_TYPE_XLIB: {
Picture *layers[] = {
- [VCR_LAYER_GRAPHA] = &vcr->xlib.grapha_picture,
- [VCR_LAYER_GRAPHB] = &vcr->xlib.graphb_picture,
+ [VCR_LAYER_GRAPHA] = &vcr->xlib.graphs_picture,
+ [VCR_LAYER_GRAPHB] = &vcr->xlib.graphs_picture,
};
Picture *tmps[] = {
- [VCR_LAYER_GRAPHA] = &vcr->xlib.tmp_a_picture,
- [VCR_LAYER_GRAPHB] = &vcr->xlib.tmp_b_picture,
+ [VCR_LAYER_GRAPHA] = &vcr->xlib.tmp_row_picture,
+ [VCR_LAYER_GRAPHB] = &vcr->xlib.tmp_row_picture,
};
vwm_xserver_t *xserver = vcr->backend->xlib.xserver;
@@ -1796,9 +1837,7 @@ void vcr_advance_phase(vcr_t *vcr, int delta)
assert(xserver);
- XRenderFillRectangle(xserver->display, PictOpSrc, vcr->xlib.grapha_picture, &chart_trans_color, vcr->phase, 0, 1, vcr->height);
- XRenderFillRectangle(xserver->display, PictOpSrc, vcr->xlib.graphb_picture, &chart_trans_color, vcr->phase, 0, 1, vcr->height);
-
+ XRenderFillRectangle(xserver->display, PictOpSrc, vcr->xlib.graphs_picture, &chart_trans_color, vcr->phase, 0, 1, vcr->height);
break;
}
#endif /* USE_XLIB */
@@ -1881,6 +1920,7 @@ int vcr_compose(vcr_t *vcr)
vcr->visible_width, height);
/* draw the graphs into the chart through the stencils being maintained by the sample callbacks */
+#if 0
XRenderComposite(xserver->display, PictOpOver, vcr->backend->xlib.grapha_fill, vcr->xlib.grapha_picture, vcr->xlib.picture,
0, 0,
vcr->phase, 0,
@@ -1891,6 +1931,19 @@ int vcr_compose(vcr_t *vcr)
vcr->phase, 0,
0, 0,
vcr->visible_width, height);
+#endif
+ /* Draw the graphs maintained by the sample callbacks into the chart.
+ * This used to use two renders for grapha/graphb layers through 8bpp stencils,
+ * but after more layers were added via palettes for the png/headless vmon use
+ * it stopped making sense to do that way. So now the callbacks maintan an argb
+ * picture and we just splat that once into the destination picture.
+ * The text/shadow layers are still stencils though.
+ */
+ XRenderComposite(xserver->display, PictOpOver, vcr->xlib.graphs_picture, None, vcr->xlib.picture,
+ vcr->phase, 0,
+ 0, 0,
+ 0, 0,
+ vcr->visible_width, height);
/* draw the shadow into the chart picture using a translucent black source drawn through the shadow mask */
XRenderComposite(xserver->display, PictOpOver, vcr->backend->xlib.shadow_fill, vcr->xlib.shadow_picture, vcr->xlib.picture,
@@ -2145,7 +2198,7 @@ static int vcr_present_xlib_to_png(vcr_t *vcr, vcr_dest_t *dest)
#define VCR_PNG_CYAN {0x00, 0xff, 0xff} /* ROWSUB0::GRAPHB */
#define VCR_PNG_MAGENTA {0xff, 0x00, 0xff} /* ROWSUB1::GRAPHA */
#define VCR_PNG_GREEN {0x00, 0xff, 0x00} /* ROWSUB1::GRAPHB */
-#define VCR_PNG_MAUVE {0xd7, 0x73, 0xd4} /* ROWSUB2::GRAPHA */
+#define VCR_PNG_BLUE {0x40, 0x60, 0xff} /* ROWSUB2::GRAPHA */
#define VCR_PNG_ORANGE {0xff, 0xa5, 0x00} /* ROWSUB2::GRAPHB */
#define VCR_PNG_CHOCOLATE {0x7b, 0x3f, 0x00} /* ROWSUB3::GRAPHA */
#define VCR_PNG_PINK {0xff, 0xc0, 0xcb} /* ROWSUB3::GRAPHB */
@@ -2195,7 +2248,7 @@ static int vcr_present_mem_to_png(vcr_t *vcr, vcr_dest_t *dest)
[VCR_LUT_ROWSUB0_B] = VCR_PNG_CYAN,
[VCR_LUT_ROWSUB1_A] = VCR_PNG_MAGENTA,
[VCR_LUT_ROWSUB1_B] = VCR_PNG_GREEN,
- [VCR_LUT_ROWSUB2_A] = VCR_PNG_MAUVE,
+ [VCR_LUT_ROWSUB2_A] = VCR_PNG_BLUE,
[VCR_LUT_ROWSUB2_B] = VCR_PNG_ORANGE,
[VCR_LUT_ROWSUB3_A] = VCR_PNG_CHOCOLATE,
[VCR_LUT_ROWSUB3_B] = VCR_PNG_PINK,
@@ -2436,10 +2489,8 @@ int vcr_present(vcr_t *vcr, vcr_present_op_t op, vcr_dest_t *dest, int x, int y,
switch (dest->type) {
case VCR_DEST_TYPE_XWINDOW: {
vwm_xserver_t *xserver = vcr->backend->xlib.xserver;
-
/* present xlib->xwindow */
/* vmon use case */
-
XRenderComposite(xserver->display, xop, vcr->xlib.picture, None, dest->xwindow.picture,
0, 0, 0, 0, /* src x,y, maxk x, y */
x, /* dst x */
© All Rights Reserved