Fix the clear() function
authorKarl Schultz <kschultz@freedesktop.org>
Fri, 5 Oct 2001 15:47:28 +0000 (15:47 +0000)
committerKarl Schultz <kschultz@freedesktop.org>
Fri, 5 Oct 2001 15:47:28 +0000 (15:47 +0000)
- add checks for the ColorMask and IndexMask (like osmesa)
- correctly handle the DD_*_BIT flags so that we don't also ask the
  swrast to clear the color buffer after we cleared it ourselves. (doh!)
  This gives nearly a 2X improvement in the frame rate in a program like
  gears.

src/mesa/drivers/windows/wmesa.c

index bd07d08..29b1108 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: wmesa.c,v 1.21 2001/10/04 19:04:56 kschultz Exp $ */
+/* $Id: wmesa.c,v 1.22 2001/10/05 15:47:28 kschultz Exp $ */
 
 /*
  * Windows (Win32) device driver for Mesa 3.4
@@ -340,6 +340,12 @@ static void clear_color( GLcontext* ctx, const GLchan color[4] )
 /*
  * Clear the specified region of the color buffer using the clear color
  * or index as specified by one of the two functions above.
+ *
+ * This procedure clears either the front and/or the back COLOR buffers.
+ * Only the "left" buffer is cleared since we are not stereo.
+ * Clearing of the other non-color buffers is left to the swrast.
+ * We also only clear the color buffers if the color masks are all 1's.
+ * Otherwise, we let swrast do it.
  */
 
 static clear(GLcontext* ctx, GLbitfield mask,
@@ -352,93 +358,106 @@ static clear(GLcontext* ctx, GLbitfield mask,
   LPWORD  lpw = (LPWORD)Current->pbPixels;
   LPBYTE  lpb = Current->pbPixels;
   int     lines;
+  const   GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask;
   
   if (all){
     x=y=0;
     width=Current->width;
     height=Current->height;
   }
-  if(Current->db_flag==GL_TRUE){
-    UINT    nBypp = Current->cColorBits / 8;
-    int     i = 0;
-    int     iSize = 0;
-    
-    if(nBypp ==1 ){
-      /* Need rectification */
-      iSize = Current->width/4;
-      bColor  = BGR8(GetRValue(Current->clearpixel),
-                    GetGValue(Current->clearpixel),
-                    GetBValue(Current->clearpixel));
-      wColor  = MAKEWORD(bColor,bColor);
-      dwColor = MAKELONG(wColor, wColor);
-    }
-    if(nBypp == 2){
-      iSize = Current->width / 2;
-      wColor = BGR16(GetRValue(Current->clearpixel),
-                    GetGValue(Current->clearpixel),
-                    GetBValue(Current->clearpixel));
-      dwColor = MAKELONG(wColor, wColor);
-    }
-    else if(nBypp == 4){
-      iSize = Current->width;
-      dwColor = BGR32(GetRValue(Current->clearpixel),
-                     GetGValue(Current->clearpixel),
-                     GetBValue(Current->clearpixel));
-    }
-    
-    while(i < iSize){
-      *lpdw = dwColor;
-      lpdw++;
-      i++;
-    }
-    
-    /* This is the 24bit case */
-    if (nBypp == 3) {
-      iSize = Current->width *3/4;
-      dwColor = BGR24(GetRValue(Current->clearpixel),
-                     GetGValue(Current->clearpixel),
-                     GetBValue(Current->clearpixel));
-      while(i < iSize){
-       *lpdw = dwColor;
-       lpb += nBypp;
-       lpdw = (LPDWORD)lpb;
-       i++;
-      }
-    }
+  
+  
+  /* sanity check - can't have right(stereo) buffers */
+  assert((mask & (DD_FRONT_RIGHT_BIT | DD_BACK_RIGHT_BIT)) == 0);
+  
+  if (*colorMask == 0xffffffff && ctx->Color.IndexMask == 0xffffffff) {
+      if (mask & DD_BACK_LEFT_BIT) {
+         /* Double-buffering - clear back buffer */
+         UINT    nBypp = Current->cColorBits / 8;
+         int     i = 0;
+         int     iSize = 0;
+         
+         assert(Current->db_flag==GL_TRUE); /* we'd better be double buffer */
+         if(nBypp ==1 ){
+             iSize = Current->width/4;
+             bColor  = BGR8(GetRValue(Current->clearpixel),
+                            GetGValue(Current->clearpixel),
+                            GetBValue(Current->clearpixel));
+             wColor  = MAKEWORD(bColor,bColor);
+             dwColor = MAKELONG(wColor, wColor);
+         }
+         if(nBypp == 2){
+             iSize = Current->width / 2;
+             wColor = BGR16(GetRValue(Current->clearpixel),
+                            GetGValue(Current->clearpixel),
+                            GetBValue(Current->clearpixel));
+             dwColor = MAKELONG(wColor, wColor);
+         }
+         else if(nBypp == 4){
+             iSize = Current->width;
+             dwColor = BGR32(GetRValue(Current->clearpixel),
+                             GetGValue(Current->clearpixel),
+                             GetBValue(Current->clearpixel));
+         }
+         
+         /* clear a line */
+         while(i < iSize){
+             *lpdw = dwColor;
+             lpdw++;
+             i++;
+         }
+         
+         /* This is the 24bit case */
+         if (nBypp == 3) {
+             iSize = Current->width *3/4;
+             dwColor = BGR24(GetRValue(Current->clearpixel),
+                             GetGValue(Current->clearpixel),
+                             GetBValue(Current->clearpixel));
+             while(i < iSize){
+                 *lpdw = dwColor;
+                 lpb += nBypp;
+                 lpdw = (LPDWORD)lpb;
+                 i++;
+             }
+         }
+         
+         i = 0;
+         if (stereo_flag)
+             lines = height /2;
+         else
+             lines = height;
+         /* copy cleared line to other lines in buffer */
+         do {
+             memcpy(lpb, Current->pbPixels, iSize*4);
+             lpb += Current->ScanWidth;
+             i++;
+         }
+         while (i<lines-1);
+         mask &= ~DD_BACK_LEFT_BIT;
+      } /* double-buffer */
+      
+      if (mask & DD_FRONT_LEFT_BIT) {
+         /* single-buffer */
+         HDC DC=DD_GETDC;
+         HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel);
+         HBRUSH Brush=CreateSolidBrush(Current->clearpixel);
+         HPEN Old_Pen=SelectObject(DC,Pen);
+         HBRUSH Old_Brush=SelectObject(DC,Brush);
+         Rectangle(DC,x,y,x+width,y+height);
+         SelectObject(DC,Old_Pen);
+         SelectObject(DC,Old_Brush);
+         DeleteObject(Pen);
+         DeleteObject(Brush);
+         DD_RELEASEDC;
+         mask &= ~DD_FRONT_LEFT_BIT;
+      } /* single-buffer */
+  } /* if masks are all 1's */
     
-    i = 0;
-    if (stereo_flag)
-      lines = height /2;
-    else
-      lines = height;
-    do {
-      memcpy(lpb, Current->pbPixels, iSize*4);
-      lpb += Current->ScanWidth;
-      i++;
-    }
-    while (i<lines-1);
-  }
-  else { /* For single buffer */
-    HDC DC=DD_GETDC;
-    HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel);
-    HBRUSH Brush=CreateSolidBrush(Current->clearpixel);
-    HPEN Old_Pen=SelectObject(DC,Pen);
-    HBRUSH Old_Brush=SelectObject(DC,Brush);
-    Rectangle(DC,x,y,x+width,y+height);
-    SelectObject(DC,Old_Pen);
-    SelectObject(DC,Old_Brush);
-    DeleteObject(Pen);
-    DeleteObject(Brush);
-    DD_RELEASEDC;
-  }
-  /* TODO need to check masks - see osmesa */
-  mask &= ~DD_FRONT_LEFT_BIT;
+  /* Call swrast if there is anything left to clear (like DEPTH) */
   if (mask)
-    _swrast_Clear( ctx, mask, all, x, y, width, height );
-  
+      _swrast_Clear( ctx, mask, all, x, y, width, height );
 }
-
+  
 
 
 static void enable( GLcontext* ctx, GLenum pname, GLboolean enable )
@@ -1413,7 +1432,6 @@ void wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
   }
   else{
     SetPixel(Current->hDC, iPixel, iScanLine, RGB(r,g,b));
-    DD_RELEASEDC;
   }
 }