summaryrefslogtreecommitdiff
path: root/src/vcr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vcr.c')
-rw-r--r--src/vcr.c143
1 files changed, 97 insertions, 46 deletions
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