diff options
Diffstat (limited to 'src/vcr.c')
-rw-r--r-- | src/vcr.c | 143 |
1 files changed, 97 insertions, 46 deletions
@@ -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 */ |