]> git.0x19.co - doomgeneric-snom360/commitdiff
X11: Improve performance by using XImage over XPixmap
authorDaniel Bomar <dbdaniel42@gmail.com>
Wed, 27 Apr 2022 06:11:39 +0000 (01:11 -0500)
committerDaniel Bomar <dbdaniel42@gmail.com>
Wed, 27 Apr 2022 06:11:39 +0000 (01:11 -0500)
This method does not need to copy pixel data greatly improving
performance. The doom framebuffer data is already in a format that Xlib
can accept so all we need to do is a single XPutImage call whenever the
engine wants us to draw a frame.

README.md
doomgeneric/doomgeneric_xlib.c

index 9b48f6e2beefa59ca36f3cfc4ba87c87a43d8b68..59b2f0741283efaf8fa218575df4673c5162bdba 100644 (file)
--- a/README.md
+++ b/README.md
@@ -25,8 +25,6 @@ Create a file named doomgeneric_yourplatform.c and just implement these function
 # platforms
 I have ported to Windows, X11, and Soso. Just look at (doomgeneric_win.c or doomgeneric_xlib.c).
 
-Note that X11 port is not efficient since it generates pixmap by XDrawPoint. It can be further improved by using X11 extensions.
-
 ## SDL
 
 ![SDL](screenshots/sdl.png)
index f6d6a31b58538228ffb5934499f9b15f91ffe948..d7e3e250790a7f75b5abdb5e09d2e61f5bd93409 100644 (file)
@@ -16,7 +16,7 @@ static Display *s_Display = NULL;
 static Window s_Window = NULL;
 static int s_Screen = 0;
 static GC s_Gc = 0;
-static Pixmap s_Pixmap = NULL;
+static XImage *s_Image = NULL;
 
 #define KEYQUEUE_SIZE 16
 
@@ -120,7 +120,7 @@ void DG_Init()
         }
     }
 
-    s_Pixmap = XCreatePixmap(s_Display, s_Window, DOOMGENERIC_RESX, DOOMGENERIC_RESY, depth);
+    s_Image = XCreateImage(s_Display, DefaultVisual(s_Display, s_Screen), depth, ZPixmap, 0, (char *)DG_ScreenBuffer, DOOMGENERIC_RESX, DOOMGENERIC_RESX, 32, 0);
 }
 
 
@@ -147,21 +147,7 @@ void DG_DrawFrame()
             }
         }
 
-        XSetForeground(s_Display, s_Gc, 0x0000FF);
-        XFillRectangle(s_Display, s_Pixmap, s_Gc, 0, 0, DOOMGENERIC_RESX, DOOMGENERIC_RESY);
-
-        for (int r = 0; r < DOOMGENERIC_RESY; ++r)
-        {
-            for (int c = 0; c < DOOMGENERIC_RESX; ++c)
-            {
-                unsigned int pixel = DG_ScreenBuffer[r * DOOMGENERIC_RESX + c];
-                XSetForeground(s_Display, s_Gc, pixel);
-                XDrawPoint(s_Display, s_Pixmap, s_Gc, c, r);
-            }
-        }
-
-        XCopyArea(s_Display, s_Pixmap, s_Window, s_Gc, 0, 0, DOOMGENERIC_RESX, DOOMGENERIC_RESY,
-            0, 0);
+        XPutImage(s_Display, s_Window, s_Gc, s_Image, 0, 0, 0, 0, DOOMGENERIC_RESX, DOOMGENERIC_RESY);
 
         //XFlush(s_Display);
     }