Browse Source

Fix XDisplay_DrawLCDWindow (). I put useless calculations out of the loop.

Fix WWDisplay_DrawScreen ().  I put useless calculations out of the loop.

After examining the hotspot, the drawing part of X (XDisplay_DrawLCDWindow () in XDisplay.c
Loop part) became a hot spot, so arrange the array for each pixel
I made it and raised drawing speed.

Version 0.0.5 alpha - from wonx-a05.tar.gz
Hiroaki Sakai 23 years ago
parent
commit
0cc1bd45ae
4 changed files with 69 additions and 40 deletions
  1. 15 0
      HISTORY
  2. 2 2
      Makefile
  3. 11 7
      WWDisplay.c
  4. 41 31
      XDisplay.c

+ 15 - 0
HISTORY

@@ -1,3 +1,18 @@
+2000/10/3(火)
+
+wonx-a05 公開
+
+XDisplay_DrawLCDWindow() を修正.無駄な計算をループ外に出した.
+
+WWDisplay_DrawScreen() を修正.無駄な計算をループ外に出した.
+
+ホットスポットを調べたら,Xの描画部分(XDisplay.c の XDisplay_DrawLCDWindow()の
+ループ部分)がホットスポットになっていたので,ピクセルごとに配列を
+作って,描画速度を上げた.
+
+
+
+
 2000/9/30(土)
 
 wonx-a04 公開

+ 2 - 2
Makefile

@@ -2,8 +2,8 @@ XINCLUDEDIR = /usr/X11R6/include
 INCLUDEDIR = .
 XLIBDIR = /usr/X11R6/lib
 
-VERSION = Wonx-a04
-PKGNAME = wonx-a04
+VERSION = Wonx-a05
+PKGNAME = wonx-a05
 
 OBJS = WWCharacter.o WWColorMap.o WWDisplay.o WWLCDPanel.o WWPalette.o WWScreen.o WWSprite.o WonxDisplay.o XDisplay.o bank.o comm.o disp.o text.o key.o sound.o system.o timer.o etc.o wonx.o
 

+ 11 - 7
WWDisplay.c

@@ -243,15 +243,17 @@ static int WWDisplay_DrawScreen(WWDisplay display, WWScreen screen)
   /* 仄凶幻丹互中中井手                                           */
 
   for (y = 0; y < lcd_panel_height; y++) {
+
+    if (mode == WWSCREEN_INSIDE_ONLY) {
+      if (y > ey) { break; }
+      if (y < sy) { y = sy - 1; continue; }
+    }
+
+    py = y + WWScreen_GetRollY(screen);
+
     for (x = 0; x < lcd_panel_width; x++) {
-      px = x + WWScreen_GetRollX(screen);
-      py = y + WWScreen_GetRollY(screen);
 
       if (mode == WWSCREEN_INSIDE_ONLY) {
-	if (y > ey) {
-	  x = lcd_panel_width - 1; y = lcd_panel_height - 1; continue;
-	}
-	if (y < sy) { x = lcd_panel_width - 1; y = sy - 1; continue; }
 	if (x > ex) { x = lcd_panel_width - 1; continue; }
 	if (x < sx) { x = sx - 1; continue; }
       } else if (mode == WWSCREEN_OUTSIDE_ONLY) {
@@ -261,6 +263,8 @@ static int WWDisplay_DrawScreen(WWDisplay display, WWScreen screen)
 	}
       }
 
+      px = x + WWScreen_GetRollX(screen);
+
       pixel = WWScreen_GetPixel(screen, px, py);
 
       /* ⑨抸縉及樺寧 */
@@ -335,7 +339,7 @@ int WWDisplay_DrawLCDPanel(WWDisplay display)
   WWSprite sprite;
 
   lcd_panel = WWDisplay_GetLCDPanel(display);
-  lcd_panel_width = WWLCDPanel_GetWidth(lcd_panel);
+  lcd_panel_width  = WWLCDPanel_GetWidth( lcd_panel);
   lcd_panel_height = WWLCDPanel_GetHeight(lcd_panel);
   color_map = WWDisplay_GetColorMap(display);
   border = WWDisplay_GetBorder(display);

+ 41 - 31
XDisplay.c

@@ -358,16 +358,23 @@ int XDisplay_Sync(XDisplay x_display)
 
 int XDisplay_DrawLCDWindow(XDisplay x_display, WWLCDPanel ww_lcd_panel)
 {
-  int x, y, n;
-  int px, py;
+  int x, y;
+  int px, py, ph;
   int num;
-  XRectangle * rectangles;
+  int n[16];
+  XRectangle * rectangles[16];
   int pixel;
   int ww_lcd_width, ww_lcd_height;
 
+  /* 隣接しているピクセルはまとめて描画するので,ピクセル数の最大値は */
+  /* 最悪の場合(縞々模様のとき)で,width * height / 2 になる.        */
   num =
-    WWLCDPanel_GetHeight(ww_lcd_panel) * WWLCDPanel_GetWidth(ww_lcd_panel);
-  rectangles = (XRectangle *)malloc(sizeof(XRectangle) * num);
+    WWLCDPanel_GetHeight(ww_lcd_panel) * WWLCDPanel_GetWidth(ww_lcd_panel) / 2;
+
+  for (pixel = 0; pixel < 16; pixel++) {
+    n[pixel] = 0;
+    rectangles[pixel] = (XRectangle *)malloc(sizeof(XRectangle) * num);
+  }
   if (rectangles == NULL)
     Error("XDisplay_DrawLCDWindow", "Cannot allocate memory.");
 
@@ -376,37 +383,38 @@ int XDisplay_DrawLCDWindow(XDisplay x_display, WWLCDPanel ww_lcd_panel)
 
   /* ここの処理はホットスポットになるので,のちのちにチューニングすること */
 
-  for (pixel = 0; pixel < 16; pixel++) {
-    n = 0;
-    for (y = 0; y < ww_lcd_height; y++) {
-      for (x = 0; x < ww_lcd_width; x++) {
-	if (pixel == WWLCDPanel_GetPixel(ww_lcd_panel, x, y)) {
-	  px = (x * x_display->width ) / ww_lcd_width;
-	  py = (y * x_display->height) / ww_lcd_height;
-	  rectangles[n].x = px;
-	  rectangles[n].y = py;
-	  rectangles[n].width  = (x+1) * x_display->width  / ww_lcd_width - px;
-	  rectangles[n].height = (y+1) * x_display->height / ww_lcd_height- py;
-
-	  /* 隣接してる同色のピクセルは,極力いっしょに描画する */
-	  x++;
-	  while ( (x < ww_lcd_width) &&
-		  (pixel == WWLCDPanel_GetPixel(ww_lcd_panel, x, y)) ) {
-	    rectangles[n].width = (x+1) * x_display->width / ww_lcd_width - px;
-	    x++;
-	  }
-	  x--;
-
-	  n++;
-	}
+  for (y = 0; y < ww_lcd_height; y++) {
+    py = (y * x_display->height) / ww_lcd_height;
+    ph = (y+1) * x_display->height / ww_lcd_height- py;
+    for (x = 0; x < ww_lcd_width; x++) {
+      pixel = WWLCDPanel_GetPixel(ww_lcd_panel, x, y);
+      px = (x * x_display->width ) / ww_lcd_width;
+      rectangles[pixel][n[pixel]].x = px;
+      rectangles[pixel][n[pixel]].y = py;
+      rectangles[pixel][n[pixel]].width  =
+	(x+1) * x_display->width  / ww_lcd_width - px;
+      rectangles[pixel][n[pixel]].height = ph;
+
+      /* 隣接してる同色のピクセルは,極力いっしょに描画する */
+      x++;
+      while ( (x < ww_lcd_width) &&
+	      (pixel == WWLCDPanel_GetPixel(ww_lcd_panel, x, y)) ) {
+	rectangles[pixel][n[pixel]].width =
+	  (x+1) * x_display->width / ww_lcd_width - px;
+	x++;
       }
+      x--;
+
+      n[pixel]++;
     }
+  }
 
-    if (n > 0) {
+  for (pixel = 0; pixel < 16; pixel++) {
+    if (n[pixel] > 0) {
       XFillRectangles(x_display->display,
 		      x_display->lcd_pixmap,
 		      x_display->color_gc[pixel],
-		      rectangles, n);
+		      rectangles[pixel], n[pixel]);
     }
   }
 
@@ -416,7 +424,9 @@ int XDisplay_DrawLCDWindow(XDisplay x_display, WWLCDPanel ww_lcd_panel)
 
   XDisplay_Sync(x_display);
 
-  free(rectangles);
+  for (pixel = 0; pixel < 16; pixel++) {
+    free(rectangles[pixel]);
+  }
 
   return (0);
 }