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. */