From 6a0fcdae0554b2e306568d9ddb0d88ba939bb3d9 Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Sat, 23 Sep 2023 01:46:39 +0200 Subject: [PATCH] various optimizations (do not execute graphic ops with gctiled if FIX_BROKEN_TILED_FILL is defined, optimize XCopy Area blits --- src/actions.c | 9 +++-- src/callback.c | 34 ++++++------------ src/draw.c | 95 ++++++++++++++++++++++++++++++++++++++++---------- src/move.c | 1 + src/select.c | 7 ++-- src/xschem.h | 5 ++- 6 files changed, 102 insertions(+), 49 deletions(-) diff --git a/src/actions.c b/src/actions.c index 54e4ae3b..65879c0f 100644 --- a/src/actions.c +++ b/src/actions.c @@ -3377,8 +3377,13 @@ void select_rect(int what, int select) RECTORDER(xctx->nl_xr,xctx->nl_yr,xctx->nl_xr2,xctx->nl_yr2); #if defined(FIX_BROKEN_TILED_FILL) || !defined(__unix__) - MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], xctx->xrect[0].x, xctx->xrect[0].y, - xctx->xrect[0].width, xctx->xrect[0].height, xctx->xrect[0].x, xctx->xrect[0].y); + /* + * MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], xctx->xrect[0].x, xctx->xrect[0].y, + * xctx->xrect[0].width, xctx->xrect[0].height, xctx->xrect[0].x, xctx->xrect[0].y); + */ + + MyXCopyAreaDouble(display, xctx->save_pixmap, xctx->window, xctx->gc[0], + xctx->nl_xr, xctx->nl_yr, xctx->nl_xr2, xctx->nl_yr2, xctx->nl_xr, xctx->nl_yr, xctx->lw); #else drawtemprect(xctx->gctiled, NOW, xctx->nl_xr,xctx->nl_yr,xctx->nl_xr2,xctx->nl_yr2); #endif diff --git a/src/callback.c b/src/callback.c index fbf6dd89..643db9dd 100644 --- a/src/callback.c +++ b/src/callback.c @@ -985,10 +985,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int void draw_crosshair(int del) { int sdw, sdp; - #if defined(FIX_BROKEN_TILED_FILL) || !defined(__unix__) - int bbox_set = xctx->bbox_set; - #endif - + dbg(1, "draw_crosshair()\n"); sdw = xctx->draw_window; sdp = xctx->draw_pixmap; @@ -996,26 +993,15 @@ void draw_crosshair(int del) xctx->draw_window = 1; #if defined(FIX_BROKEN_TILED_FILL) || !defined(__unix__) - if(!bbox_set) { - bbox(START,0.0, 0.0, 0.0, 0.0); - bbox(ADD, X_TO_XSCHEM(xctx->areax1), xctx->prev_crossy - xctx->lw, - X_TO_XSCHEM(xctx->areax2), xctx->prev_crossy + xctx->lw); - bbox(SET, 0.0, 0.0, 0.0, 0.0); - } - MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], xctx->xrect[0].x, xctx->xrect[0].y, - xctx->xrect[0].width, xctx->xrect[0].height, xctx->xrect[0].x, xctx->xrect[0].y); - if(!bbox_set) { - bbox(END, 0.0, 0.0, 0.0, 0.0); - bbox(START,0.0, 0.0, 0.0, 0.0); - bbox(ADD, xctx->prev_crossx - xctx->lw, Y_TO_XSCHEM(xctx->areay1), - xctx->prev_crossx + xctx->lw, Y_TO_XSCHEM(xctx->areay2)); - bbox(SET, 0.0, 0.0, 0.0, 0.0); - } - MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], xctx->xrect[0].x, xctx->xrect[0].y, - xctx->xrect[0].width, xctx->xrect[0].height, xctx->xrect[0].x, xctx->xrect[0].y); - if(!bbox_set) { - bbox(END, 0.0, 0.0, 0.0, 0.0); - } + MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], + 0, (int)Y_TO_SCREEN(xctx->prev_crossy) - 2 * INT_WIDTH(xctx->lw), + xctx->xrect[0].width, 4 * INT_WIDTH(xctx->lw), + 0, (int)Y_TO_SCREEN(xctx->prev_crossy) - 2 * INT_WIDTH(xctx->lw)); + + MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], + (int)X_TO_SCREEN(xctx->prev_crossx) - 2 * INT_WIDTH(xctx->lw), 0, + 4 * INT_WIDTH(xctx->lw), xctx->xrect[0].height, + (int)X_TO_SCREEN(xctx->prev_crossx) - 2 * INT_WIDTH(xctx->lw), 0); #endif draw_selection(xctx->gc[SELLAYER], 0); drawtempline(xctx->gctiled, NOW, X_TO_XSCHEM(xctx->areax1), diff --git a/src/draw.c b/src/draw.c index 132ad711..c2092727 100644 --- a/src/draw.c +++ b/src/draw.c @@ -406,6 +406,10 @@ void draw_temp_string(GC gctext, int what, const char *str, short rot, short fli int tmp; double dtmp; if(!has_x) return; + #if defined(FIX_BROKEN_TILED_FILL) || !defined(__unix__) + if(gctext == xctx->gctiled) return; + #endif + dbg(2, "draw_string(): string=%s\n",str); if(!text_bbox(str, xscale, yscale, rot, flip, hcenter, vcenter, x1,y1, &textx1,&texty1,&textx2,&texty2, &tmp, &dtmp)) return; @@ -724,6 +728,10 @@ void draw_temp_symbol(int what, GC gc, int n,int layer,short tmp_flip, short rot if(xctx->inst[n].ptr == -1) return; if(!has_x) return; + #if defined(FIX_BROKEN_TILED_FILL) || !defined(__unix__) + if(gc == xctx->gctiled) return; + #endif + if( (xctx->inst[n].flags & HIDE_INST) || (xctx->hide_symbols==1 && (xctx->inst[n].ptr+ xctx->sym)->prop_ptr && !strcmp( (xctx->inst[n].ptr+ xctx->sym)->type, "subcircuit") ) || @@ -1086,13 +1094,13 @@ void drawline(int c, int what, double linex1, double liney1, double linex2, doub if(dash) { dash_arr[0] = dash_arr[1] = (char) dash; XSetDashes(display, xctx->gc[c], 0, dash_arr, 1); - XSetLineAttributes (display, xctx->gc[c], INT_WIDTH(xctx->lw), xDashType, xCap, xJoin); + XSetLineAttributes (display, xctx->gc[c], XLINEWIDTH(xctx->lw), xDashType, xCap, xJoin); } if(xctx->draw_window) XDrawLine(display, xctx->window, xctx->gc[c], (int)x1, (int)y1, (int)x2, (int)y2); if(xctx->draw_pixmap) XDrawLine(display, xctx->save_pixmap, xctx->gc[c], (int)x1, (int)y1, (int)x2, (int)y2); if(dash) { - XSetLineAttributes (display, xctx->gc[c], INT_WIDTH(xctx->lw), LineSolid, LINECAP, LINEJOIN); + XSetLineAttributes (display, xctx->gc[c], XLINEWIDTH(xctx->lw), LineSolid, LINECAP, LINEJOIN); } #if !defined(__unix__) && HAS_CAIRO==1 check_cairo_drawline(ct, c, x1, y1, x2, y2, dash); @@ -1120,7 +1128,7 @@ void drawline(int c, int what, double linex1, double liney1, double linex2, doub #if !defined(__unix__) && HAS_CAIRO==1 check_cairo_drawline(ct, c, x1, y1, x2, y2, dash); #endif - XSetLineAttributes (display, xctx->gc[c], INT_WIDTH(xctx->lw), LineSolid, LINECAP , LINEJOIN); + XSetLineAttributes (display, xctx->gc[c], XLINEWIDTH(xctx->lw), LineSolid, LINECAP , LINEJOIN); } } else if((what & END) && i) @@ -1153,6 +1161,10 @@ void drawtempline(GC gc, int what, double linex1,double liney1,double linex2,dou double x1,y1,x2,y2; if(!has_x) return; + #if defined(FIX_BROKEN_TILED_FILL) || !defined(__unix__) + if(gc == xctx->gctiled) return; + #endif + if(what & ADD) { if(i>=CADDRAWBUFFERSIZE) @@ -1201,7 +1213,7 @@ void drawtempline(GC gc, int what, double linex1,double liney1,double linex2,dou XSetLineAttributes (display, gc, INT_BUS_WIDTH(xctx->lw), LineSolid, LINECAP , LINEJOIN); XDrawLine(display, xctx->window, gc, (int)x1, (int)y1, (int)x2, (int)y2); - XSetLineAttributes (display, gc, INT_WIDTH(xctx->lw), LineSolid, LINECAP , LINEJOIN); + XSetLineAttributes (display, gc, XLINEWIDTH(xctx->lw), LineSolid, LINECAP , LINEJOIN); } } @@ -1226,6 +1238,10 @@ void drawtemparc(GC gc, int what, double x, double y, double r, double a, double double xx1, yy1, xx2, yy2; /* complete circle bbox in screen coords */ if(!has_x) return; + #if defined(FIX_BROKEN_TILED_FILL) || !defined(__unix__) + if(gc == xctx->gctiled) return; + #endif + if(what & ADD) { if(i>=CADDRAWBUFFERSIZE) @@ -1434,7 +1450,7 @@ void drawarc(int c, int what, double x, double y, double r, double a, double b, char dash_arr[2]; dash_arr[0] = dash_arr[1] = (char)dash; XSetDashes(display, xctx->gc[c], 0, dash_arr, 1); - XSetLineAttributes (display, xctx->gc[c], INT_WIDTH(xctx->lw), xDashType, xCap, xJoin); + XSetLineAttributes (display, xctx->gc[c], XLINEWIDTH(xctx->lw), xDashType, xCap, xJoin); } if(xctx->draw_window) { @@ -1457,7 +1473,7 @@ void drawarc(int c, int what, double x, double y, double r, double a, double b, } } if(dash) { - XSetLineAttributes (display, xctx->gc[c], INT_WIDTH(xctx->lw) ,LineSolid, LINECAP , LINEJOIN); + XSetLineAttributes (display, xctx->gc[c], XLINEWIDTH(xctx->lw) ,LineSolid, LINECAP , LINEJOIN); } } } @@ -1631,7 +1647,7 @@ void drawpolygon(int c, int what, double *x, double *y, int points, int poly_fil char dash_arr[2]; dash_arr[0] = dash_arr[1] = (char)dash; XSetDashes(display, xctx->gc[c], 0, dash_arr, 1); - XSetLineAttributes (display, xctx->gc[c], INT_WIDTH(xctx->lw), xDashType, xCap, xJoin); + XSetLineAttributes (display, xctx->gc[c], XLINEWIDTH(xctx->lw), xDashType, xCap, xJoin); } if(xctx->draw_window) XDrawLines(display, xctx->window, xctx->gc[c], p, points, CoordModeOrigin); if(xctx->draw_pixmap) @@ -1645,7 +1661,7 @@ void drawpolygon(int c, int what, double *x, double *y, int points, int poly_fil } } if(dash) { - XSetLineAttributes (display, xctx->gc[c], INT_WIDTH(xctx->lw) ,LineSolid, LINECAP , LINEJOIN); + XSetLineAttributes (display, xctx->gc[c], XLINEWIDTH(xctx->lw) ,LineSolid, LINECAP , LINEJOIN); } my_free(_ALLOC_ID_, &p); } @@ -1657,6 +1673,10 @@ void drawtemppolygon(GC g, int what, double *x, double *y, int points) int i; short sx, sy; if(!has_x) return; + #if defined(FIX_BROKEN_TILED_FILL) || !defined(__unix__) + if(g == xctx->gctiled) return; + #endif + polygon_bbox(x, y, points, &x1,&y1,&x2,&y2); x1=X_TO_SCREEN(x1); y1=Y_TO_SCREEN(y1); @@ -1694,7 +1714,7 @@ void drawrect(int c, int what, double rectx1,double recty1,double rectx2,double if(dash) { dash_arr[0] = dash_arr[1] = (char)dash; XSetDashes(display, xctx->gc[c], 0, dash_arr, 1); - XSetLineAttributes (display, xctx->gc[c], INT_WIDTH(xctx->lw), xDashType, xCap, xJoin); + XSetLineAttributes (display, xctx->gc[c], XLINEWIDTH(xctx->lw), xDashType, xCap, xJoin); } if(xctx->draw_window) XDrawRectangle(display, xctx->window, xctx->gc[c], (int)x1, (int)y1, (unsigned int)x2 - (unsigned int)x1, @@ -1706,7 +1726,7 @@ void drawrect(int c, int what, double rectx1,double recty1,double rectx2,double (unsigned int)y2 - (unsigned int)y1); } if(dash) { - XSetLineAttributes (display, xctx->gc[c], INT_WIDTH(xctx->lw) ,LineSolid, LINECAP, LINEJOIN); + XSetLineAttributes (display, xctx->gc[c], XLINEWIDTH(xctx->lw) ,LineSolid, LINECAP, LINEJOIN); } } } @@ -1747,6 +1767,10 @@ void drawtemprect(GC gc, int what, double rectx1,double recty1,double rectx2,dou double x1,y1,x2,y2; if(!has_x) return; + #if defined(FIX_BROKEN_TILED_FILL) || !defined(__unix__) + if(gc == xctx->gctiled) return; + #endif + if(what & NOW) { x1=X_TO_SCREEN(rectx1); @@ -1974,11 +1998,11 @@ static void set_thick_waves(int what, int wcnt, int wave_col, Graph_ctx *gr) if(what) { if(gr->hilight_wave == wcnt) XSetLineAttributes (display, xctx->gc[wave_col], - INT_WIDTH(2.4 * gr->linewidth_mult * xctx->lw) ,LineSolid, LINECAP , LINEJOIN); + XLINEWIDTH(2.4 * gr->linewidth_mult * xctx->lw) ,LineSolid, LINECAP , LINEJOIN); } else { if(gr->hilight_wave == wcnt) XSetLineAttributes (display, xctx->gc[wave_col], - INT_WIDTH(gr->linewidth_mult * xctx->lw) ,LineSolid, LINECAP , LINEJOIN); + XLINEWIDTH(gr->linewidth_mult * xctx->lw) ,LineSolid, LINECAP , LINEJOIN); } } @@ -2120,7 +2144,7 @@ static void draw_graph_bus_points(const char *ntok, int n_bits, SPICE_DATA **idx for(p=0;pgc[p], - INT_WIDTH(gr->linewidth_mult * xctx->lw), LineSolid, LINECAP , LINEJOIN); + XLINEWIDTH(gr->linewidth_mult * xctx->lw), LineSolid, LINECAP , LINEJOIN); } if(gr->logx) { @@ -2171,7 +2195,7 @@ static void draw_graph_bus_points(const char *ntok, int n_bits, SPICE_DATA **idx set_thick_waves(0, wcnt, wave_col, gr); } for(p=0;pgc[p], INT_WIDTH(xctx->lw), LineSolid, LINECAP , LINEJOIN); + XSetLineAttributes(display, xctx->gc[p], XLINEWIDTH(xctx->lw), LineSolid, LINECAP , LINEJOIN); } } #define MAX_POLY_POINTS 4096*16 @@ -2191,7 +2215,7 @@ static void draw_graph_points(int idx, int first, int last, dbg(1, "draw_graph_points: idx=%d, first=%d, last=%d, wcnt=%d\n", idx, first, last, wcnt); for(p=0;pgc[p], - INT_WIDTH(gr->linewidth_mult * xctx->lw), LineSolid, LINECAP , LINEJOIN); + XLINEWIDTH(gr->linewidth_mult * xctx->lw), LineSolid, LINECAP , LINEJOIN); } if(idx == -1) return; digital = gr->digital; @@ -2241,7 +2265,7 @@ static void draw_graph_points(int idx, int first, int last, set_thick_waves(0, wcnt, wave_col, gr); } else dbg(1, "skipping wave: %s\n", xctx->graph_names[idx]); for(p=0;pgc[p], INT_WIDTH(xctx->lw), LineSolid, LINECAP , LINEJOIN); + XSetLineAttributes(display, xctx->gc[p], XLINEWIDTH(xctx->lw), LineSolid, LINECAP , LINEJOIN); } } @@ -3633,6 +3657,7 @@ void draw(void) const char *textfont; #endif + dbg(1, "draw()\n"); if(!xctx || xctx->no_draw) return; #if HAS_CAIRO==1 #ifndef __unix__ @@ -3853,15 +3878,47 @@ int XSetTile(Display* display, GC gc, Pixmap s_pixmap) void MyXCopyArea(Display* display, Drawable src, Drawable dest, GC gc, int src_x, int src_y, unsigned int width, unsigned int height, int dest_x, int dest_y) { + dbg(1, "MyXCopyArea()\n"); #if !defined(__unix__) XCopyArea(display, src, dest, gc, src_x, src_y, width, height, dest_x, dest_y); #if HAS_CAIRO==1 my_cairo_fill(xctx->cairo_save_sfc, dest_x, dest_y, width, height); #endif - #elif (defined(__unix__) && HAS_CAIRO==1) || DRAW_ALL_CAIRO==1 - cairo_set_source_surface(xctx->cairo_ctx, xctx->cairo_save_sfc, 0, 0); - cairo_paint(xctx->cairo_ctx); + /* + * #elif (defined(__unix__) && HAS_CAIRO==1) || DRAW_ALL_CAIRO==1 + * cairo_set_source_surface(xctx->cairo_ctx, xctx->cairo_save_sfc, 0, 0); + * cairo_paint(xctx->cairo_ctx); + */ #else XCopyArea(display, src, dest, gc, src_x, src_y, width, height, dest_x, dest_y); #endif } + +void MyXCopyAreaDouble(Display* display, Drawable src, Drawable dest, GC gc, + double sx1, double sy1, double sx2, double sy2, + double dx1, double dy1, double lw) +{ + double isx1, isy1, isx2, isy2, idx1, idy1; + unsigned int width, height; + + isx1=X_TO_SCREEN(sx1) - 2 * INT_WIDTH(lw); + isy1=Y_TO_SCREEN(sy1) - 2 * INT_WIDTH(lw); + isx2=X_TO_SCREEN(sx2) + 2 * INT_WIDTH(lw); + isy2=Y_TO_SCREEN(sy2) + 2 * INT_WIDTH(lw); + + idx1=X_TO_SCREEN(dx1) - 2 * INT_WIDTH(lw); + idy1=Y_TO_SCREEN(dy1) - 2 * INT_WIDTH(lw); + + width = (unsigned int)isx2 - (unsigned int)isx1; + height = (unsigned int)isy2 - (unsigned int)isy1; + + #if !defined(__unix__) + XCopyArea(display, src, dest, gc, (int)isx1, (int)isy1, width, height, (int)idx1, (int)idy1); + #if HAS_CAIRO==1 + my_cairo_fill(xctx->cairo_save_sfc, dest_x, dest_y, width, height); + #endif + #else + XCopyArea(display, src, dest, gc, (int)isx1, (int)isy1, width, height, (int)idx1, (int)idy1); + #endif +} + diff --git a/src/move.c b/src/move.c index d5b38165..d50031ce 100644 --- a/src/move.c +++ b/src/move.c @@ -193,6 +193,7 @@ void draw_selection(GC g, int interruptable) int customfont; #endif + dbg(1,"draw_selection\n"); if(g != xctx->gctiled) xctx->movelastsel = xctx->lastsel; #if defined(FIX_BROKEN_TILED_FILL) || !defined(__unix__) else { diff --git a/src/select.c b/src/select.c index e612d636..11a1242d 100644 --- a/src/select.c +++ b/src/select.c @@ -819,7 +819,7 @@ void unselect_all(int dr) #if HAS_CAIRO==1 int customfont; #endif - dbg(2, "unselect_all(1): start\n"); + dbg(1, "unselect_all(1): start\n"); xctx->ui_state = 0; xctx->lastsel = 0; @@ -925,11 +925,12 @@ void unselect_all(int dr) my_snprintf(str, S(str), "%s/%s", user_conf_dir, ".selection.sch"); /* 20161115 PWD->HOME */ xunlink(str); #if defined(FIX_BROKEN_TILED_FILL) || !defined(__unix__) - if(xctx->save_pixmap && xctx->window) + if(xctx->save_pixmap && xctx->window) { MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], xctx->xrect[0].x, xctx->xrect[0].y, xctx->xrect[0].width, xctx->xrect[0].height, xctx->xrect[0].x, xctx->xrect[0].y); + if(tclgetboolvar("draw_crosshair")) draw_crosshair(0); + } #endif - dbg(2, "unselect_all(1): done\n"); } diff --git a/src/xschem.h b/src/xschem.h index 8bf1a583..7c1a8573 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -408,7 +408,8 @@ do { \ #define SWAP(a,b, tmp) do { tmp = a; a = b; b = tmp; } while(0) -#define INT_WIDTH(x) ( tclgetboolvar("change_lw") ? ( (int)(x) == 0 ? 1 : (int)(x) ) : (int)(x) ) +#define XLINEWIDTH(x) ( tclgetboolvar("change_lw") ? ( (int)(x) == 0 ? 1 : (int)(x) ) : (int)(x) ) +#define INT_WIDTH(x) ((int)(x) == 0 ? 1 : (int)(x)) #define INT_BUS_WIDTH(x) ( (int)( (BUS_WIDTH) * (x) ) == 0 ? 1 : (int)( (BUS_WIDTH) * (x) ) ) /* set do double if you need more precision at the expense of memory */ @@ -1303,6 +1304,8 @@ extern void draw_temp_symbol(int what, GC gc, int n,int layer, extern void draw_temp_string(GC gc,int what, const char *str, short rot, short flip, int hcenter, int vcenter, double x1, double y1, double xscale, double yscale); +extern void MyXCopyAreaDouble(Display* display, Drawable src, Drawable dest, GC gc, + double sx1, double sy1, double sx2, double sy2, double dx1, double dy1, double lw); extern void draw(void); extern void clip_xy_to_short(double x, double y, short *sx, short *sy); extern int clip( double*,double*,double*,double*);