diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2025-07-28 01:06:00 -0700 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2025-07-28 19:11:28 -0700 |
commit | b29a3a3a033d21351093d7101ae6106d3e485c31 (patch) | |
tree | bef09c58d51b6369ccb107b8ddf5efbef486b027 | |
parent | a7ad112deef0a4dc6e0ab912300e64569e635352 (diff) |
WIP DO NOT MERGErss
-rw-r--r-- | src/charts.c | 230 | ||||
-rw-r--r-- | src/vcr.c | 143 |
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 */ @@ -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 */ |