From 74cf5266f9e2632c014868414bcf6518a4a6e951 Mon Sep 17 00:00:00 2001 From: Kim Woelders Date: Sun, 3 Feb 2008 16:52:38 +0000 Subject: [PATCH] Avoid some pixel copying in certain situations around ImageclassApplyCopy. SVN revision: 33669 --- src/dialog.c | 11 +++---- src/iclass.c | 84 +++++++++++++++++++++++++--------------------------- src/iclass.h | 10 +++++-- src/menus.c | 42 +++++++++++++------------- src/x.c | 21 ++++++++++++- src/xwin.h | 6 +++- 6 files changed, 100 insertions(+), 74 deletions(-) diff --git a/src/dialog.c b/src/dialog.c index a9c0d11c..ebd3579e 100644 --- a/src/dialog.c +++ b/src/dialog.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors - * Copyright (C) 2004-2007 Kim Woelders + * Copyright (C) 2004-2008 Kim Woelders * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -473,12 +473,13 @@ DialogRedraw(Dialog * d) FreePmapMask(&(d->pmm_bg)); ImageclassApplyCopy(d->iclass, d->win, d->w, d->h, 0, 0, STATE_NORMAL, - &(d->pmm_bg), 0, ST_DIALOG); + &(d->pmm_bg), IC_FLAG_NONE, ST_DIALOG); if (d->pmm_bg.pmap == None) return; EGetWindowBackgroundPixmap(d->win); - EXCopyArea(d->pmm_bg.pmap, WinGetPmap(d->win), 0, 0, d->w, d->h, 0, 0); + EXCopyAreaTiled(d->pmm_bg.pmap, None, WinGetPmap(d->win), 0, 0, d->w, d->h, + 0, 0); d->redraw = 1; @@ -1732,8 +1733,8 @@ DialogDrawItem(Dialog * d, DItem * di) if (!di->text) break; if (!d->redraw) - EXCopyArea(d->pmm_bg.pmap, WinGetPmap(d->win), di->x, di->y, - di->w, di->h, di->x, di->y); + EXCopyAreaTiled(d->pmm_bg.pmap, None, WinGetPmap(d->win), + di->x, di->y, di->w, di->h, di->x, di->y); TextDraw(di->tclass, d->win, WinGetPmap(d->win), 0, 0, state, di->text, x, di->y, w, 99999, 17, TextclassGetJustification(di->tclass)); break; diff --git a/src/iclass.c b/src/iclass.c index 2c3aa6c4..41e52f36 100644 --- a/src/iclass.c +++ b/src/iclass.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors - * Copyright (C) 2004-2007 Kim Woelders + * Copyright (C) 2004-2008 Kim Woelders * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -917,7 +917,7 @@ ImageclassGetImageBlended(ImageClass * ic, Win win, int w, int h, int active, static void ImagestateMakePmapMask(ImageState * is, Win win, PmapMask * pmm, - int make_mask, int w, int h, int image_type) + int pmapflags, int w, int h, int image_type) { #ifdef ENABLE_TRANSPARENCY EImage *ii = NULL; @@ -957,7 +957,7 @@ ImagestateMakePmapMask(ImageState * is, Win win, PmapMask * pmm, pmm->h = h; EImageRenderOnDrawable(ii, win, pmap, 0, 0, 0, w, h); - if (make_mask && !(flags & ICLASS_ATTR_NO_CLIP)) + if ((pmapflags & IC_FLAG_MAKE_MASK) && !(flags & ICLASS_ATTR_NO_CLIP)) { if (EImageHasAlpha(is->im)) { @@ -975,7 +975,7 @@ ImagestateMakePmapMask(ImageState * is, Win win, PmapMask * pmm, } else #else - make_mask = 0; + pmapflags = 0; image_type = 0; #endif /* ENABLE_TRANSPARENCY */ if (is->pixmapfillstyle == FILL_STRETCH) @@ -1156,7 +1156,8 @@ ITApply(Win win, ImageClass * ic, ImageState * is, { PmapMask pmm; - ImagestateMakePmapMask(is, win, &pmm, 1, w, h, image_type); + ImagestateMakePmapMask(is, win, &pmm, IC_FLAG_MAKE_MASK, w, h, + image_type); if (pmm.pmap) { @@ -1225,13 +1226,36 @@ ImageclassApply(ImageClass * ic, Win win, int active, int sticky, int state, 0); } +static void +PmapMaskTile(PmapMask * pmm, Win win, unsigned int w, unsigned int h) +{ + Pixmap pmap, mask; + + pmap = ECreatePixmap(win, w, h, 0); + if (pmap == None) + return; + EXCopyAreaTiled(pmm->pmap, None, pmap, 0, 0, w, h, 0, 0); + + mask = None; + if (pmm->mask != None) + mask = ECreatePixmap(win, w, h, 1); + if (mask != None) + EXCopyAreaTiled(pmm->mask, None, mask, 0, 0, w, h, 0, 0); + + FreePmapMask(pmm); + pmm->type = 0; + pmm->w = w; + pmm->h = h; + pmm->pmap = pmap; + pmm->mask = mask; +} + void ImageclassApplyCopy(ImageClass * ic, Win win, int w, int h, int active, int sticky, int state, - PmapMask * pmm, int make_mask, int image_type) + PmapMask * pmm, int pmapflags, int image_type) { ImageState *is; - GC gc; if (pmm == NULL) return; @@ -1252,44 +1276,14 @@ ImageclassApplyCopy(ImageClass * ic, Win win, int w, int h, /* Imlib2 will not render pixmaps with dimensions > 8192 */ if (is->im && w <= 8192 && h <= 8192) { - ImagestateMakePmapMask(is, win, pmm, make_mask, w, h, image_type); + ImagestateMakePmapMask(is, win, pmm, pmapflags, w, h, image_type); - if (pmm->pmap) + if ((pmapflags & IC_FLAG_FULL_SIZE) && pmm->pmap && + (pmm->w != w || pmm->h != h)) { - if (pmm->w != w || pmm->h != h) - { - /* Create new full sized pixmaps and fill them with the */ - /* pmap and mask tiles */ - Pixmap tp = 0, tm = 0; - XGCValues gcv; - - tp = ECreatePixmap(win, w, h, 0); - gcv.fill_style = FillTiled; - gcv.tile = pmm->pmap; - gcv.ts_x_origin = 0; - gcv.ts_y_origin = 0; - gc = EXCreateGC(tp, GCFillStyle | GCTile | - GCTileStipXOrigin | GCTileStipYOrigin, &gcv); - XFillRectangle(disp, tp, gc, 0, 0, w, h); - EXFreeGC(gc); - if (pmm->mask) - { - tm = ECreatePixmap(win, w, h, 1); - gcv.fill_style = FillTiled; - gcv.tile = pmm->mask; - gcv.ts_x_origin = 0; - gcv.ts_y_origin = 0; - gc = EXCreateGC(tm, GCFillStyle | GCTile | - GCTileStipXOrigin | GCTileStipYOrigin, - &gcv); - XFillRectangle(disp, tm, gc, 0, 0, w, h); - EXFreeGC(gc); - } - FreePmapMask(pmm); - pmm->type = 0; - pmm->pmap = tp; - pmm->mask = tm; - } + /* Create new full sized pixmaps and fill them with the */ + /* pmap and mask tiles */ + PmapMaskTile(pmm, win, w, h); } if ((is->unloadable) || (Conf.memory_paranoia)) @@ -1300,6 +1294,7 @@ ImageclassApplyCopy(ImageClass * ic, Win win, int w, int h, } else { + GC gc; Pixmap pmap; ImagestateColorsAlloc(is); @@ -1536,7 +1531,8 @@ ImageclassIpc(const char *params) return; } - ImageclassApplyCopy(ic, win, w, h, 0, 0, st, &pmm, 1, ST_SOLID); + ImageclassApplyCopy(ic, win, w, h, 0, 0, st, &pmm, + IC_FLAG_MAKE_MASK | IC_FLAG_FULL_SIZE, ST_SOLID); IpcPrintf("0x%08lx 0x%08lx\n", pmm.pmap, pmm.mask); EDestroyWin(win); } diff --git a/src/iclass.h b/src/iclass.h index f5b2cdaa..3ec94f02 100644 --- a/src/iclass.h +++ b/src/iclass.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors - * Copyright (C) 2004-2007 Kim Woelders + * Copyright (C) 2004-2008 Kim Woelders * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -63,6 +63,12 @@ #define ICLASS_ATTR_NO_CLIP 0x04 /* Don't apply clip mask */ #define ICLASS_ATTR_USE_CM 0x08 /* Use colormodifier */ +/* ImageclassApplyCopy flags */ +#define IC_FLAG_NONE 0x00 /* No flags */ +#define IC_FLAG_WRITABLE 0x01 /* Provide writable pixmaps */ +#define IC_FLAG_MAKE_MASK 0x02 /* Make mask */ +#define IC_FLAG_FULL_SIZE 0x04 /* Make full size pixmaps */ + /* cmclass.c */ #if ENABLE_COLOR_MODIFIERS void CreateCurve(ModCurve * c); @@ -114,7 +120,7 @@ void ImageclassApply(ImageClass * ic, Win win, void ImageclassApplyCopy(ImageClass * ic, Win win, int w, int h, int active, int sticky, int state, PmapMask * pmm, - int make_mask, int image_type); + int pmapflags, int image_type); EImage *ImageclassGetImageBlended(ImageClass * ic, Win win, int w, int h, int active, int sticky, int state, diff --git a/src/menus.c b/src/menus.c index c9551ff3..ab1b02b9 100644 --- a/src/menus.c +++ b/src/menus.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors - * Copyright (C) 2004-2007 Kim Woelders + * Copyright (C) 2004-2008 Kim Woelders * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -912,7 +912,7 @@ MenuRealize(Menu * m) static void MenuRedraw(Menu * m) { - int i, j, w, h; + int i, j; if (m->redraw) { @@ -927,12 +927,13 @@ MenuRedraw(Menu * m) if (!m->style->use_item_bg) { - w = m->w; - h = m->h; FreePmapMask(&m->pmm); - ImageclassApplyCopy(m->style->bg_iclass, m->win, w, h, 0, - 0, STATE_NORMAL, &m->pmm, 1, ST_MENU); - ESetWindowBackgroundPixmap(m->win, m->pmm.pmap); + ImageclassApplyCopy(m->style->bg_iclass, m->win, m->w, m->h, 0, + 0, STATE_NORMAL, &m->pmm, IC_FLAG_MAKE_MASK, + ST_MENU); + EGetWindowBackgroundPixmap(m->win); + EXCopyAreaTiled(m->pmm.pmap, None, WinGetPmap(m->win), + 0, 0, m->w, m->h, 0, 0); EShapeCombineMask(m->win, ShapeBounding, 0, 0, m->pmm.mask, ShapeSet); EClearWindow(m->win); for (i = 0; i < m->num; i++) @@ -959,10 +960,11 @@ MenuDrawItem(Menu * m, MenuItem * mi, char shape, int state) if (!mi_pmm->pmap) { - GC gc; int x, y, w, h; int item_type; ImageClass *ic; + GC gc; + PmapMask pmm; EGetGeometry(mi->win, NULL, &x, &y, &w, &h, NULL, NULL); @@ -976,27 +978,25 @@ MenuDrawItem(Menu * m, MenuItem * mi, char shape, int state) if (!m->style->use_item_bg) { gc = EXCreateGC(m->pmm.pmap, 0, NULL); - XCopyArea(disp, m->pmm.pmap, mi_pmm->pmap, gc, x, y, w, h, 0, 0); + XCopyArea(disp, WinGetPmap(m->win), mi_pmm->pmap, gc, x, y, w, h, + 0, 0); if ((mi->state != STATE_NORMAL) || (mi->child)) { - PmapMask pmm; - - ImageclassApplyCopy(ic, mi->win, w, h, 0, 0, - mi->state, &pmm, 1, item_type); - if (pmm.mask) - { - XSetClipMask(disp, gc, pmm.mask); - XSetClipOrigin(disp, gc, 0, 0); - } - XCopyArea(disp, pmm.pmap, mi_pmm->pmap, gc, 0, 0, w, h, 0, 0); + ImageclassApplyCopy(ic, mi->win, w, h, 0, 0, mi->state, &pmm, + IC_FLAG_MAKE_MASK, item_type); + EXCopyAreaTiled(pmm.pmap, pmm.mask, mi_pmm->pmap, + 0, 0, w, h, 0, 0); FreePmapMask(&pmm); } EXFreeGC(gc); } else { - ImageclassApplyCopy(ic, mi->win, w, h, 0, 0, mi->state, - mi_pmm, 1, item_type); + ImageclassApplyCopy(ic, mi->win, w, h, 0, 0, mi->state, &pmm, + IC_FLAG_MAKE_MASK, item_type); + EXCopyAreaTiled(pmm.pmap, pmm.mask, mi_pmm->pmap, + 0, 0, w, h, 0, 0); + FreePmapMask(&pmm); } if (mi->text) diff --git a/src/x.c b/src/x.c index 93146230..480b5008 100644 --- a/src/x.c +++ b/src/x.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors - * Copyright (C) 2004-2007 Kim Woelders + * Copyright (C) 2004-2008 Kim Woelders * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -1578,6 +1578,25 @@ EXCopyArea(Drawable src, Drawable dst, int sx, int sy, unsigned int w, EXFreeGC(gc); } +void +EXCopyAreaTiled(Drawable src, Pixmap mask, Drawable dst, int sx, int sy, + unsigned int w, unsigned int h, int dx, int dy) +{ + GC gc; + XGCValues gcv; + + gcv.fill_style = FillTiled; + gcv.tile = src; + gcv.ts_x_origin = sx; + gcv.ts_y_origin = sy; + gcv.clip_mask = mask; + gc = EXCreateGC(dst, GCFillStyle | + GCTile | GCTileStipXOrigin | GCTileStipYOrigin | GCClipMask, + &gcv); + XFillRectangle(disp, dst, gc, dx, dy, w, h); + EXFreeGC(gc); +} + GC EXCreateGC(Drawable draw, unsigned long mask, XGCValues * val) { diff --git a/src/xwin.h b/src/xwin.h index d815857d..d1391c7e 100644 --- a/src/xwin.h +++ b/src/xwin.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors - * Copyright (C) 2004-2007 Kim Woelders + * Copyright (C) 2004-2008 Kim Woelders * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -233,6 +233,10 @@ int EXGetGeometry(Window xwin, Window * root_return, void EXCopyArea(Drawable src, Drawable dst, int sx, int sy, unsigned int w, unsigned int h, int dx, int dy); +void EXCopyAreaTiled(Drawable src, Pixmap mask, Drawable dst, + int sx, int sy, + unsigned int w, unsigned int h, + int dx, int dy); void EXWarpPointer(Window xwin, int x, int y);