Re: [AD] XOR drawing under X11 (and what is _xwin_in_gfx_call)

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


On Sat, 2004-11-20 at 16:55 -0800, Chris wrote:
> What you're saying makes sense. XOR mode isn't really used that much by 
> speed-intensive programs either.. not on video bitmaps, anyway. I only 
> added it because I figured X would be able to do it a lot faster than we 
> could (perhaps hw accelerated).
> 
> Did you try making X11 only use the GXsolid state and see if that fixes 
> the problem?
> 

Yes, it does. And I found another way to create droppings:

I disabled the Allegro mouse completely, and did some XOR drawing.
Simply moving another window across the Allegro window now leaves
droppings.

I can't explain neither this not the mouse droppings fully. Somehow XOR
operations are different from solid ones, and strage things happen with
them..

Therefore, I made the attached patch, which simply removes direct XOR
drawing again. Immediately everything works perfectly. And since it's
hard for me to keep overview in long functions, I split the direct
updating into separate functions.. the optimizer will inline them again
anyway.

> 
> > For example nobody knows
> > what _xwin_in_gfx_call is for exactly, apparently it can be set also
> > with the pthread driver, so it's not just something for the signals
> > version.
> 
> This needs to be looked at again. Two graphics calls should not be able 

I'm almost sure now this is only for the signals version - just not sure
how it works. If something wants to draw while drawing is in progress,
it only updates the back-buffer(?)

> to affect video bitmaps at the same time with the new locking mechanism. 
> But it seems I misunderstood that the driver functions need to handle 
> the locking, instead of the Allegro base system.
> 

No, the locks all were right. If any lock is removed so two X11
functions can execute concurrently, I get async replies.

-- 
Elias Pschernig
Index: include/xalleg.h
===================================================================
RCS file: /cvsroot/alleg/allegro/include/xalleg.h,v
retrieving revision 1.21
diff -u -p -r1.21 xalleg.h
--- include/xalleg.h	30 Oct 2004 23:00:54 -0000	1.21
+++ include/xalleg.h	24 Nov 2004 21:32:19 -0000
@@ -132,7 +132,6 @@ extern struct _xwin_type
    char application_name[1024];
    char application_class[1024];
 
-   int real_drawing_mode;
    int drawing_mode_ok;
 
 #ifdef ALLEGRO_MULTITHREADED
Index: src/x/xvtable.c
===================================================================
RCS file: /cvsroot/alleg/allegro/src/x/xvtable.c,v
retrieving revision 1.17
diff -u -p -r1.17 xvtable.c
--- src/x/xvtable.c	30 Oct 2004 22:44:57 -0000	1.17
+++ src/x/xvtable.c	24 Nov 2004 21:32:20 -0000
@@ -62,27 +62,162 @@ static void _xwin_clear_to_color(BITMAP 
 void _xwin_drawing_mode(void)
 {
    if (!_xwin.matching_formats) {
-      if (_drawing_mode == DRAW_MODE_SOLID)
-	 _xwin.drawing_mode_ok = TRUE;
-      else
-	 _xwin.drawing_mode_ok = FALSE;
-
-      _xwin.real_drawing_mode = GXcopy;
-      XSetState(_xwin.display, _xwin.gc, 0, 0, GXcopy, -1);
       return;
    }
 
-   _xwin.drawing_mode_ok = TRUE;
+   /* Only SOLID can be handled directly by X11. */
    if(_drawing_mode == DRAW_MODE_SOLID)
-      _xwin.real_drawing_mode = GXcopy;
-   else if (_drawing_mode == DRAW_MODE_XOR)
-      _xwin.real_drawing_mode = GXxor;
-   else {
+       _xwin.drawing_mode_ok = TRUE;
+   else
       _xwin.drawing_mode_ok = FALSE;
-      _xwin.real_drawing_mode = GXcopy;
-   }
+}
+
+
+
+/* Direct X11 version of the function. */
+static int direct_putpixel(BITMAP *dst, int dx, int dy, int color)
+{
+   if (!_xwin.matching_formats || !_xwin.drawing_mode_ok)
+      return 0;
+
+   dx += dst->x_ofs - _xwin.scroll_x;
+   dy += dst->y_ofs - _xwin.scroll_y;
+
+   if((dx >= _xwin.screen_width) || (dx < 0) || 
+      (dy >= _xwin.screen_height) || (dy < 0))
+      return 1;
+
+   XLOCK();
+   XSetForeground(_xwin.display, _xwin.gc, color);
+   XDrawPoint(_xwin.display, _xwin.window, _xwin.gc, dx, dy);
+   XUNLOCK();
+
+   return 1;
+}
+
+
+
+/* Direct X11 version of the function. */
+static int direct_hline(BITMAP *dst, int dx1, int dy, int dx2, int color)
+{
+   if (!_xwin.matching_formats || !_xwin.drawing_mode_ok)
+      return 0;
+
+   dx1 += dst->x_ofs - _xwin.scroll_x;
+   dx2 += dst->x_ofs - _xwin.scroll_x;
+   dy += dst->y_ofs - _xwin.scroll_y;
+
+   if (dx1 < 0)
+      dx1 = 0;
+   if (dx2 >= _xwin.screen_width)
+      dx2 = _xwin.screen_width - 1;
+   if ((dx1 > dx2) || (dy < 0) || (dy >= _xwin.screen_height))
+      return 1;
+
+   XLOCK();
+   XSetForeground(_xwin.display, _xwin.gc, color);
+   XDrawLine(_xwin.display, _xwin.window, _xwin.gc, dx1, dy, dx2, dy);
+   XUNLOCK();;
+
+   return 1;
+}
+
+
+
+/* Direct X11 version of the function. */
+static int direct_vline(BITMAP *dst, int dx, int dy1, int dy2, int color)
+{
+   if (!_xwin.matching_formats || !_xwin.drawing_mode_ok)
+      return 0;
+
+   dx += dst->x_ofs - _xwin.scroll_x;
+   dy1 += dst->y_ofs - _xwin.scroll_y;
+   dy2 += dst->y_ofs - _xwin.scroll_y;
 
-   XSetState(_xwin.display, _xwin.gc, 0, 0, _xwin.real_drawing_mode, -1);
+   if (dy1 < 0)
+      dy1 = 0;
+   if (dy2 >= _xwin.screen_height)
+      dy2 = _xwin.screen_height - 1;
+   if ((dy1 > dy2) || (dx < 0) || (dx >= _xwin.screen_width))
+      return 1;
+
+   XLOCK();
+   XSetForeground(_xwin.display, _xwin.gc, color);
+   XDrawLine(_xwin.display, _xwin.window, _xwin.gc, dx, dy1, dx, dy2);
+   XUNLOCK();
+
+   return 1;
+}
+
+
+
+/* Direct X11 version of the function. */
+static int direct_rectfill(BITMAP *dst, int dx1, int dy1, int dx2, int dy2, int color)
+{
+   if (!_xwin.matching_formats || !_xwin.drawing_mode_ok)
+      return 0;
+
+   dx1 += dst->x_ofs - _xwin.scroll_x;
+   dx2 += dst->x_ofs - _xwin.scroll_x;
+   dy1 += dst->y_ofs - _xwin.scroll_y;
+   dy2 += dst->y_ofs - _xwin.scroll_y;
+
+   if (dx1 < 0)
+      dx1 = 0;
+   if (dx2 >= _xwin.screen_width)
+      dx2 = _xwin.screen_width - 1;
+   if (dx1 > dx2)
+      return 1;
+
+   if (dy1 < 0)
+      dy1 = 0;
+   if (dy2 >= _xwin.screen_height)
+      dy2 = _xwin.screen_height - 1;
+   if (dy1 > dy2)
+      return 1;
+
+   XLOCK();
+   XSetForeground(_xwin.display, _xwin.gc, color);
+   XFillRectangle(_xwin.display, _xwin.window, _xwin.gc, dx1, dy1, dx2-dx1+1, dy2-dy1+1);
+   XUNLOCK();
+
+   return 1;
+}
+
+
+
+/* Direct X11 version of the function. */
+static int direct_clear_to_color(BITMAP *dst, int color)
+{
+   int dx1, dy1, dx2, dy2;
+   if (!_xwin.matching_formats)
+      return 0;
+
+   dx1 = dst->cl + dst->x_ofs - _xwin.scroll_x;
+   dx2 = dst->cr + dst->x_ofs - 1 - _xwin.scroll_x;
+   dy1 = dst->ct + dst->y_ofs - _xwin.scroll_y;
+   dy2 = dst->cb + dst->y_ofs - 1 - _xwin.scroll_y;
+
+   if (dx1 < 0)
+      dx1 = 0;
+   if (dx2 >= _xwin.screen_width)
+      dx2 = _xwin.screen_width - 1;
+   if (dx1 > dx2)
+      return 1;
+
+   if (dy1 < 0)
+      dy1 = 0;
+   if (dy2 >= _xwin.screen_height)
+      dy2 = _xwin.screen_height - 1;
+   if (dy1 > dy2)
+      return 1;
+
+   XLOCK();
+   XSetForeground(_xwin.display, _xwin.gc, color);
+   XFillRectangle(_xwin.display, _xwin.window, _xwin.gc, dx1, dy1, dx2-dx1+1, dy2-dy1+1);
+   XUNLOCK();
+
+   return 1;
 }
 
 
@@ -152,13 +287,7 @@ void _xwin_unlock(BITMAP *bmp)
  */
 static void _xwin_update_video_bitmap(BITMAP *dst, int x, int y, int w, int h)
 {
-   if (_xwin.real_drawing_mode != GXcopy)
-      XSetState(_xwin.display, _xwin.gc, 0, 0, GXcopy, -1);
-
    _xwin_update_screen(x + dst->x_ofs, y + dst->y_ofs, w, h);
-
-   if (_xwin.real_drawing_mode != GXcopy)
-      XSetState(_xwin.display, _xwin.gc, 0, 0, _xwin.real_drawing_mode, -1);
 }
 
 
@@ -180,22 +309,10 @@ static void _xwin_putpixel(BITMAP *dst, 
    _xwin_vtable.putpixel(dst, dx, dy, color);
    _xwin_in_gfx_call = 0;
 
-   if (_xwin.matching_formats && _xwin.drawing_mode_ok)
-   {
-      dx += dst->x_ofs - _xwin.scroll_x;
-      dy += dst->y_ofs - _xwin.scroll_y;
-
-      if((dx >= _xwin.screen_width) || (dx < 0) || 
-	 (dy >= _xwin.screen_height) || (dy < 0))
-	 return;
+   if (direct_putpixel(dst, dx, dy, color))
+      return;
 
-      _xwin_lock(NULL);
-      XSetForeground(_xwin.display, _xwin.gc, color);
-      XDrawPoint(_xwin.display, _xwin.window, _xwin.gc, dx, dy);
-      _xwin_unlock(NULL);
-   }
-   else
-      _xwin_update_video_bitmap(dst, dx, dy, 1, 1);
+   _xwin_update_video_bitmap(dst, dx, dy, 1, 1);
 }
 
 
@@ -229,25 +346,10 @@ static void _xwin_hline(BITMAP *dst, int
    _xwin_vtable.hline(dst, dx1, dy, dx2, color);
    _xwin_in_gfx_call = 0;
 
-   if (_xwin.matching_formats && _xwin.drawing_mode_ok) {
-      dx1 += dst->x_ofs - _xwin.scroll_x;
-      dx2 += dst->x_ofs - _xwin.scroll_x;
-      dy += dst->y_ofs - _xwin.scroll_y;
-
-      if (dx1 < 0)
-	 dx1 = 0;
-      if (dx2 >= _xwin.screen_width)
-	 dx2 = _xwin.screen_width - 1;
-      if ((dx1 > dx2) || (dy < 0) || (dy >= _xwin.screen_height))
-	 return;
+   if (direct_hline(dst, dx1, dy, dx2, color))
+      return;
 
-      _xwin_lock(NULL);
-      XSetForeground(_xwin.display, _xwin.gc, color);
-      XDrawLine(_xwin.display, _xwin.window, _xwin.gc, dx1, dy, dx2, dy);
-      _xwin_unlock(NULL);
-   }
-   else
-      _xwin_update_video_bitmap(dst, dx1, dy, dx2 - dx1 + 1, 1);
+   _xwin_update_video_bitmap(dst, dx1, dy, dx2 - dx1 + 1, 1);
 }
 
 
@@ -281,25 +383,10 @@ static void _xwin_vline(BITMAP *dst, int
    _xwin_vtable.vline(dst, dx, dy1, dy2, color);
    _xwin_in_gfx_call = 0;
 
-   if (_xwin.matching_formats && _xwin.drawing_mode_ok) {
-      dx += dst->x_ofs - _xwin.scroll_x;
-      dy1 += dst->y_ofs - _xwin.scroll_y;
-      dy2 += dst->y_ofs - _xwin.scroll_y;
-
-      if (dy1 < 0)
-	 dy1 = 0;
-      if (dy2 >= _xwin.screen_height)
-	 dy2 = _xwin.screen_height - 1;
-      if ((dy1 > dy2) || (dx < 0) || (dx >= _xwin.screen_width))
-	 return;
+   if (direct_vline(dst, dx, dy1, dy2, color))
+      return;
 
-      _xwin_lock(NULL);
-      XSetForeground(_xwin.display, _xwin.gc, color);
-      XDrawLine(_xwin.display, _xwin.window, _xwin.gc, dx, dy1, dx, dy2);
-      _xwin_unlock(NULL);
-   }
-   else
-      _xwin_update_video_bitmap(dst, dx, dy1, 1, dy2 - dy1 + 1);
+   _xwin_update_video_bitmap(dst, dx, dy1, 1, dy2 - dy1 + 1);
 }
 
 
@@ -346,33 +433,10 @@ static void _xwin_rectfill(BITMAP *dst, 
    _xwin_vtable.rectfill(dst, dx1, dy1, dx2, dy2, color);
    _xwin_in_gfx_call = 0;
 
-   if (_xwin.matching_formats && _xwin.drawing_mode_ok) {
-      dx1 += dst->x_ofs - _xwin.scroll_x;
-      dx2 += dst->x_ofs - _xwin.scroll_x;
-      dy1 += dst->y_ofs - _xwin.scroll_y;
-      dy2 += dst->y_ofs - _xwin.scroll_y;
-
-      if (dx1 < 0)
-	 dx1 = 0;
-      if (dx2 >= _xwin.screen_width)
-	 dx2 = _xwin.screen_width - 1;
-      if (dx1 > dx2)
-	 return;
-
-      if (dy1 < 0)
-	 dy1 = 0;
-      if (dy2 >= _xwin.screen_height)
-	 dy2 = _xwin.screen_height - 1;
-      if (dy1 > dy2)
-	 return;
+   if (direct_rectfill(dst, dx1, dy1, dx2, dy2, color))
+      return;
 
-      _xwin_lock(NULL);
-      XSetForeground(_xwin.display, _xwin.gc, color);
-      XFillRectangle(_xwin.display, _xwin.window, _xwin.gc, dx1, dy1, dx2-dx1+1, dy2-dy1+1);
-      _xwin_unlock(NULL);
-   }
-   else
-      _xwin_update_video_bitmap(dst, dx1, dy1, dx2 - dx1 + 1, dy2 - dy1 + 1);
+   _xwin_update_video_bitmap(dst, dx1, dy1, dx2 - dx1 + 1, dy2 - dy1 + 1);
 }
 
 
@@ -391,33 +455,10 @@ static void _xwin_clear_to_color(BITMAP 
    _xwin_vtable.clear_to_color(dst, color);
    _xwin_in_gfx_call = 0;
 
-   if (_xwin.matching_formats && (_drawing_mode == DRAW_MODE_SOLID)) {
-      int dx1 = dst->cl + dst->x_ofs - _xwin.scroll_x;
-      int dx2 = dst->cr + dst->x_ofs - 1 - _xwin.scroll_x;
-      int dy1 = dst->ct + dst->y_ofs - _xwin.scroll_y;
-      int dy2 = dst->cb + dst->y_ofs - 1 - _xwin.scroll_y;
-
-      if (dx1 < 0)
-	 dx1 = 0;
-      if (dx2 >= _xwin.screen_width)
-	 dx2 = _xwin.screen_width - 1;
-      if (dx1 > dx2)
-	 return;
-
-      if (dy1 < 0)
-	 dy1 = 0;
-      if (dy2 >= _xwin.screen_height)
-	 dy2 = _xwin.screen_height - 1;
-      if (dy1 > dy2)
-	 return;
+   if (direct_clear_to_color(dst, color))
+      return;
 
-      _xwin_lock(NULL);
-      XSetForeground(_xwin.display, _xwin.gc, color);
-      XFillRectangle(_xwin.display, _xwin.window, _xwin.gc, dx1, dy1, dx2-dx1+1, dy2-dy1+1);
-      _xwin_unlock(NULL);
-   }
-   else
-      _xwin_update_video_bitmap(dst, dst->cl, dst->ct, dst->cr - dst->cl, dst->cb - dst->ct);
+   _xwin_update_video_bitmap(dst, dst->cl, dst->ct, dst->cr - dst->cl, dst->cb - dst->ct);
 }
 
 
Index: src/x/xwin.c
===================================================================
RCS file: /cvsroot/alleg/allegro/src/x/xwin.c,v
retrieving revision 1.81
diff -u -p -r1.81 xwin.c
--- src/x/xwin.c	20 Nov 2004 16:42:42 -0000	1.81
+++ src/x/xwin.c	24 Nov 2004 21:32:22 -0000
@@ -136,7 +136,6 @@ struct _xwin_type _xwin =
    XWIN_DEFAULT_APPLICATION_NAME,       /* application_name */
    XWIN_DEFAULT_APPLICATION_CLASS,      /* application_class */
 
-   GXcopy,      /* real_drawing_mode */
    TRUE,        /* drawing_mode_ok */
 
 #ifdef ALLEGRO_MULTITHREADED
@@ -2313,11 +2312,9 @@ static void _xwin_private_process_event(
 	    (*_xwin_mouse_interrupt)(0, 0, 0, mouse_buttons);
 	 break;
       case Expose:
-	 XSetState(_xwin.display, _xwin.gc, 0, 0, GXcopy, -1);
 	 /* Request to redraw part of the window.  */
 	 (*_xwin_window_redrawer)(event->xexpose.x, event->xexpose.y,
 				     event->xexpose.width, event->xexpose.height);
-	 XSetState(_xwin.display, _xwin.gc, 0, 0, _xwin.real_drawing_mode, -1);
 	 break;
       case MappingNotify:
 	 /* Keyboard mapping changed.  */


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/