X11: mildly optimize drawing
There is no real performance impact on modern systems.
This commit is contained in:
parent
d82be07807
commit
b196ef4f08
45
nncmpp.c
45
nncmpp.c
|
@ -1357,6 +1357,7 @@ static struct app_context
|
||||||
int xkb_base_event_code; ///< Xkb base event code
|
int xkb_base_event_code; ///< Xkb base event code
|
||||||
Window x11_window; ///< Application window
|
Window x11_window; ///< Application window
|
||||||
Pixmap x11_pixmap; ///< Off-screen bitmap
|
Pixmap x11_pixmap; ///< Off-screen bitmap
|
||||||
|
Region x11_clip; ///< Invalidated region
|
||||||
Picture x11_pixmap_picture; ///< XRender wrap for x11_pixmap
|
Picture x11_pixmap_picture; ///< XRender wrap for x11_pixmap
|
||||||
XftDraw *xft_draw; ///< Xft rendering context
|
XftDraw *xft_draw; ///< Xft rendering context
|
||||||
XftFont *xft_regular; ///< Regular font
|
XftFont *xft_regular; ///< Regular font
|
||||||
|
@ -5673,19 +5674,27 @@ x11_render_spectrum (struct widget *self)
|
||||||
x11_render_padding (self);
|
x11_render_padding (self);
|
||||||
|
|
||||||
#ifdef WITH_FFTW
|
#ifdef WITH_FFTW
|
||||||
int step = self->width / g.spectrum.bars;
|
XRectangle rectangles[g.spectrum.bars];
|
||||||
|
int step = self->width / N_ELEMENTS (rectangles);
|
||||||
for (int i = 0; i < g.spectrum.bars; i++)
|
for (int i = 0; i < g.spectrum.bars; i++)
|
||||||
{
|
{
|
||||||
float value = g.spectrum.spectrum[i];
|
int height = round ((self->height - 2) * g.spectrum.spectrum[i]);
|
||||||
int height = round ((self->height - 2) * value);
|
rectangles[i] = (XRectangle)
|
||||||
XRenderFillRectangle (g.dpy, PictOpSrc,
|
{
|
||||||
g.x11_pixmap_picture, x11_fg (self),
|
|
||||||
self->x + i * step,
|
self->x + i * step,
|
||||||
self->y + self->height - 1 - height,
|
self->y + self->height - 1 - height,
|
||||||
step,
|
step,
|
||||||
height);
|
height,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
#endif // WITH_FFTW
|
|
||||||
|
XRenderFillRectangles (g.dpy, PictOpSrc, g.x11_pixmap_picture,
|
||||||
|
x11_fg (self), rectangles, N_ELEMENTS (rectangles));
|
||||||
|
#endif // WITH_FFTW
|
||||||
|
|
||||||
|
// Enable the spectrum_redraw() hack.
|
||||||
|
XRectangle r = { self->x, self->y, self->width, self->height };
|
||||||
|
XUnionRectWithRegion (&r, g.x11_clip, g.x11_clip);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct widget *
|
static struct widget *
|
||||||
|
@ -5812,20 +5821,26 @@ x11_render (void)
|
||||||
{
|
{
|
||||||
XRenderFillRectangle (g.dpy, PictOpSrc, g.x11_pixmap_picture,
|
XRenderFillRectangle (g.dpy, PictOpSrc, g.x11_pixmap_picture,
|
||||||
&x11_default_bg, 0, 0, g.ui_width, g.ui_height);
|
&x11_default_bg, 0, 0, g.ui_width, g.ui_height);
|
||||||
|
|
||||||
// TODO: Consider setting clip rectangles (not particularly needed).
|
|
||||||
LIST_FOR_EACH (struct widget, w, g.widgets.head)
|
LIST_FOR_EACH (struct widget, w, g.widgets.head)
|
||||||
if (w->width && w->height)
|
if (w->width && w->height)
|
||||||
w->on_render (w);
|
w->on_render (w);
|
||||||
|
|
||||||
|
XRectangle r = { 0, 0, g.ui_width, g.ui_height };
|
||||||
|
XUnionRectWithRegion (&r, g.x11_clip, g.x11_clip);
|
||||||
poller_idle_set (&g.xpending_event);
|
poller_idle_set (&g.xpending_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
x11_flip (void)
|
x11_flip (void)
|
||||||
{
|
{
|
||||||
|
// This exercise in futility doesn't seem to affect CPU usage much.
|
||||||
|
XRectangle r = {};
|
||||||
|
XClipBox (g.x11_clip, &r);
|
||||||
XCopyArea (g.dpy, g.x11_pixmap, g.x11_window,
|
XCopyArea (g.dpy, g.x11_pixmap, g.x11_window,
|
||||||
DefaultGC (g.dpy, DefaultScreen (g.dpy)),
|
DefaultGC (g.dpy, DefaultScreen (g.dpy)),
|
||||||
0, 0, g.ui_width, g.ui_height, 0, 0);
|
r.x, r.y, r.width, r.height, r.x, r.y);
|
||||||
|
|
||||||
|
XSubtractRegion (g.x11_clip, g.x11_clip, g.x11_clip);
|
||||||
poller_idle_set (&g.xpending_event);
|
poller_idle_set (&g.xpending_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5834,6 +5849,7 @@ x11_destroy (void)
|
||||||
{
|
{
|
||||||
XDestroyIC (g.x11_ic);
|
XDestroyIC (g.x11_ic);
|
||||||
XCloseIM (g.x11_im);
|
XCloseIM (g.x11_im);
|
||||||
|
XDestroyRegion (g.x11_clip);
|
||||||
XDestroyWindow (g.dpy, g.x11_window);
|
XDestroyWindow (g.dpy, g.x11_window);
|
||||||
XRenderFreePicture (g.dpy, g.x11_pixmap_picture);
|
XRenderFreePicture (g.dpy, g.x11_pixmap_picture);
|
||||||
XFreePixmap (g.dpy, g.x11_pixmap);
|
XFreePixmap (g.dpy, g.x11_pixmap);
|
||||||
|
@ -6072,9 +6088,13 @@ on_x11_event (XEvent *ev)
|
||||||
switch (ev->type)
|
switch (ev->type)
|
||||||
{
|
{
|
||||||
case Expose:
|
case Expose:
|
||||||
if (!ev->xexpose.count)
|
{
|
||||||
poller_idle_set (&g.flip_event);
|
XRectangle r = { ev->xexpose.x, ev->xexpose.y,
|
||||||
|
ev->xexpose.width, ev->xexpose.height };
|
||||||
|
XUnionRectWithRegion (&r, g.x11_clip, g.x11_clip);
|
||||||
|
poller_idle_set (&g.flip_event);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case ConfigureNotify:
|
case ConfigureNotify:
|
||||||
if (g.ui_width == ev->xconfigure.width
|
if (g.ui_width == ev->xconfigure.width
|
||||||
&& g.ui_height == ev->xconfigure.height)
|
&& g.ui_height == ev->xconfigure.height)
|
||||||
|
@ -6308,6 +6328,7 @@ x11_init (void)
|
||||||
g.x11_window = XCreateWindow (g.dpy, RootWindow (g.dpy, screen), 100, 100,
|
g.x11_window = XCreateWindow (g.dpy, RootWindow (g.dpy, screen), 100, 100,
|
||||||
g.ui_width, g.ui_height, 0, CopyFromParent, InputOutput, visual,
|
g.ui_width, g.ui_height, 0, CopyFromParent, InputOutput, visual,
|
||||||
CWEventMask | CWBackPixel | CWBitGravity, &attrs);
|
CWEventMask | CWBackPixel | CWBitGravity, &attrs);
|
||||||
|
g.x11_clip = XCreateRegion ();
|
||||||
|
|
||||||
XTextProperty prop = {};
|
XTextProperty prop = {};
|
||||||
char *name = PROGRAM_NAME;
|
char *name = PROGRAM_NAME;
|
||||||
|
|
Loading…
Reference in New Issue