Merge branch 'gallium-noconstbuf'
[mesa.git] / src / mesa / drivers / windows / gdi / wmesa.c
index 0dfd7a6b393d9d0f1a650a6eb7e3e155e701ef40..76c825a0904da13c83f3866166df86c076ac2ece 100644 (file)
@@ -6,12 +6,14 @@
 #include "wmesadef.h"
 #include "colors.h"
 #include <GL/wmesa.h>
+#include <winuser.h>
 #include "context.h"
 #include "extensions.h"
 #include "framebuffer.h"
 #include "renderbuffer.h"
 #include "drivers/common/driverfuncs.h"
-#include "array_cache/acache.h"
+#include "drivers/common/meta.h"
+#include "vbo/vbo.h"
 #include "swrast/swrast.h"
 #include "swrast_setup/swrast_setup.h"
 #include "tnl/tnl.h"
@@ -55,11 +57,13 @@ wmesa_free_framebuffer(HDC hdc)
        prev = pwfb;
     }
     if (pwfb) {
+        struct gl_framebuffer *fb;
        if (pwfb == FirstFramebuffer)
            FirstFramebuffer = pwfb->next;
        else
            prev->next = pwfb->next;
-       free(pwfb);
+        fb = &pwfb->Base;
+        _mesa_reference_framebuffer(&fb, NULL); 
     }
 }
 
@@ -114,9 +118,10 @@ static void wmSetPixelFormat(WMesaFramebuffer pwfb, HDC hDC)
 {
     pwfb->cColorBits = GetDeviceCaps(hDC, BITSPIXEL);
 
-    // Only 16 and 32 bit targets are supported now
+    /* Only 16 and 32 bit targets are supported now */
     assert(pwfb->cColorBits == 0 ||
           pwfb->cColorBits == 16 || 
+          pwfb->cColorBits == 24 || 
           pwfb->cColorBits == 32);
 
     switch(pwfb->cColorBits){
@@ -126,6 +131,7 @@ static void wmSetPixelFormat(WMesaFramebuffer pwfb, HDC hDC)
     case 16:
        pwfb->pixelformat = PF_5R6G5B;
        break;
+    case 24:
     case 32:
        pwfb->pixelformat = PF_8R8G8B;
        break;
@@ -281,11 +287,7 @@ static void clear_color(GLcontext *ctx, const GLfloat color[4])
  * Clearing of the other non-color buffers is left to the swrast. 
  */ 
 
-static void clear(GLcontext *ctx, 
-                 GLbitfield mask, 
-                 GLboolean all, 
-                 GLint xFoo, GLint yFoo,
-                 GLint widthFoo, GLint heightFoo) 
+static void clear(GLcontext *ctx, GLbitfield mask)
 {
 #define FLIP(Y)  (ctx->DrawBuffer->Height - (Y) - 1)
     const GLint x = ctx->DrawBuffer->_Xmin;
@@ -299,11 +301,11 @@ static void clear(GLcontext *ctx,
 
     /* Let swrast do all the work if the masks are not set to
      * clear all channels. */
-    if (ctx->Color.ColorMask[0] != 0xff ||
-       ctx->Color.ColorMask[1] != 0xff ||
-       ctx->Color.ColorMask[2] != 0xff ||
-       ctx->Color.ColorMask[3] != 0xff) {
-       _swrast_Clear(ctx, mask, all, x, y, width, height); 
+    if (!ctx->Color.ColorMask[0][0] ||
+       !ctx->Color.ColorMask[0][1] ||
+       !ctx->Color.ColorMask[0][2] ||
+       !ctx->Color.ColorMask[0][3]) {
+       _swrast_Clear(ctx, mask);
        return;
     }
 
@@ -322,7 +324,8 @@ static void clear(GLcontext *ctx,
        
        /* Try for a fast clear - clearing entire buffer with a single
         * byte value. */
-       if (all) { /* entire buffer */
+       if (width == ctx->DrawBuffer->Width &&
+            height == ctx->DrawBuffer->Height) { /* entire buffer */
            /* Now check for an easy clear value */
            switch (bytesPerPixel) {
            case 1:
@@ -435,7 +438,7 @@ static void clear(GLcontext *ctx,
     
     /* 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);
   
 #undef FLIP
 } 
@@ -460,23 +463,84 @@ static void write_rgba_span_front(const GLcontext *ctx,
                                   const GLubyte rgba[][4], 
                                   const GLubyte mask[] )
 {
-    WMesaContext pwc = wmesa_context(ctx);
-    GLuint i;
-    
-    (void) ctx;
-    y=FLIP(y);
-    if (mask) {
-       for (i=0; i<n; i++)
-           if (mask[i])
-               SetPixel(pwc->hDC, x+i, y, RGB(rgba[i][RCOMP], rgba[i][GCOMP], 
-                                              rgba[i][BCOMP]));
-    }
-    else {
-       for (i=0; i<n; i++)
-           SetPixel(pwc->hDC, x+i, y, RGB(rgba[i][RCOMP], rgba[i][GCOMP], 
-                                          rgba[i][BCOMP]));
-    }
-    
+   WMesaContext pwc = wmesa_context(ctx);
+   WMesaFramebuffer pwfb = wmesa_lookup_framebuffer(pwc->hDC);
+   CONST BITMAPINFO bmi=
+   {
+      {
+         sizeof(BITMAPINFOHEADER),
+         n, 1, 1, 32, BI_RGB, 0, 1, 1, 0, 0
+      }
+   };
+   HBITMAP bmp=0;
+   HDC mdc=0;
+   typedef union
+   {
+      unsigned i;
+      struct {
+         unsigned b:8, g:8, r:8, a:8;
+      };
+   } BGRA;
+   BGRA *bgra, c;
+   int i;
+
+   if (n < 16) {   // the value 16 is just guessed
+      y=FLIP(y);
+      if (mask) {
+         for (i=0; i<n; i++)
+            if (mask[i])
+               SetPixel(pwc->hDC, x+i, y,
+                        RGB(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]));
+      }
+      else {
+         for (i=0; i<n; i++)
+            SetPixel(pwc->hDC, x+i, y,
+                     RGB(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]));
+      }
+   }
+   else {
+      if (!pwfb) {
+         _mesa_problem(NULL, "wmesa: write_rgba_span_front on unknown hdc");
+         return;
+      }
+      bgra=malloc(n*sizeof(BGRA));
+      if (!bgra) {
+         _mesa_problem(NULL, "wmesa: write_rgba_span_front: out of memory");
+         return;
+      }
+      c.a=0;
+      if (mask) {
+         for (i=0; i<n; i++) {
+            if (mask[i]) {
+               c.r=rgba[i][RCOMP];
+               c.g=rgba[i][GCOMP];
+               c.b=rgba[i][BCOMP];
+               c.a=rgba[i][ACOMP];
+               bgra[i]=c;
+            }
+            else
+               bgra[i].i=0;
+         }
+      }
+      else {
+         for (i=0; i<n; i++) {
+            c.r=rgba[i][RCOMP];
+            c.g=rgba[i][GCOMP];
+            c.b=rgba[i][BCOMP];
+            c.a=rgba[i][ACOMP];
+            bgra[i]=c;
+         }
+      }
+      bmp=CreateBitmap(n, 1,  1, 32, bgra);
+      mdc=CreateCompatibleDC(pwfb->hDC);
+      SelectObject(mdc, bmp);
+      y=FLIP(y);
+      BitBlt(pwfb->hDC, x, y, n, 1, mdc, 0, 0, SRCCOPY);
+      SelectObject(mdc, 0);
+      DeleteObject(bmp);
+      DeleteDC(mdc);
+      free(bgra);
+   }
 }
 
 /* Write a horizontal span of RGB color pixels with a boolean mask. */
@@ -795,6 +859,195 @@ static void read_rgba_pixels_32(const GLcontext *ctx,
 }
 
 
+/*********************************************************************/
+
+/* DOUBLE BUFFER 24-bit */
+
+#define WMSETPIXEL24(pwc, y, x, r, g, b) { \
+LPBYTE lpb = ((LPBYTE)((pwc)->pbPixels + (pwc)->ScanWidth * (y)) + (3 * x)); \
+lpb[0] = (b); \
+lpb[1] = (g); \
+lpb[2] = (r); }
+
+/* Write a horizontal span of RGBA color pixels with a boolean mask. */
+static void write_rgba_span_24(const GLcontext *ctx, 
+                              struct gl_renderbuffer *rb, 
+                              GLuint n, GLint x, GLint y,
+                              const GLubyte rgba[][4], 
+                              const GLubyte mask[] )
+{
+    WMesaContext pwc = wmesa_context(ctx);
+    WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
+    GLuint i;
+    LPBYTE lpb;
+
+    (void) ctx;
+    
+    y=FLIP(y);
+    lpb = ((LPBYTE)(pwfb->pbPixels + pwfb->ScanWidth * y)) + (3 * x);
+    if (mask) {
+       for (i=0; i<n; i++)
+           if (mask[i]) {
+                lpb[3*i] = rgba[i][BCOMP];
+                lpb[3*i+1] = rgba[i][GCOMP];
+                lpb[3*i+2] = rgba[i][RCOMP];
+           }
+    }
+    else {
+           for (i=0; i<n; i++) {
+            *lpb++ = rgba[i][BCOMP];
+            *lpb++ = rgba[i][GCOMP];
+            *lpb++ = rgba[i][RCOMP];
+           }
+    }
+}
+
+
+/* Write a horizontal span of RGB color pixels with a boolean mask. */
+static void write_rgb_span_24(const GLcontext *ctx, 
+                             struct gl_renderbuffer *rb, 
+                             GLuint n, GLint x, GLint y,
+                             const GLubyte rgb[][3], 
+                             const GLubyte mask[] )
+{
+    WMesaContext pwc = wmesa_context(ctx);
+    WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
+    GLuint i;
+    LPBYTE lpb;
+
+    (void) ctx;
+    
+    y=FLIP(y);
+    lpb = ((LPBYTE)(pwfb->pbPixels + pwfb->ScanWidth * y)) + (3 * x);
+    if (mask) {
+       for (i=0; i<n; i++)
+           if (mask[i]) {
+            lpb[3*i] = rgb[i][BCOMP];
+            lpb[3*i+1] = rgb[i][GCOMP];
+            lpb[3*i+2] = rgb[i][RCOMP];
+           }
+    }
+    else {
+       for (i=0; i<n; i++) {
+               *lpb++ = rgb[i][BCOMP];
+               *lpb++ = rgb[i][GCOMP];
+               *lpb++ = rgb[i][RCOMP];
+       }
+    }
+}
+
+/*
+ * Write a horizontal span of pixels with a boolean mask.  The current color
+ * is used for all pixels.
+ */
+static void write_mono_rgba_span_24(const GLcontext *ctx, 
+                                   struct gl_renderbuffer *rb,
+                                   GLuint n, GLint x, GLint y,
+                                   const GLchan color[4], 
+                                   const GLubyte mask[])
+{
+    LPBYTE lpb;
+    GLuint i;
+    WMesaContext pwc = wmesa_context(ctx);
+    WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
+    lpb = ((LPBYTE)(pwfb->pbPixels + pwfb->ScanWidth * y)) + (3 * x);
+    y=FLIP(y);
+    if (mask) {
+       for (i=0; i<n; i++)
+           if (mask[i]) {
+               lpb[3*i] = color[BCOMP];
+               lpb[3*i+1] = color[GCOMP];
+               lpb[3*i+2] = color[RCOMP];
+           }
+    }
+    else
+       for (i=0; i<n; i++) {
+               *lpb++ = color[BCOMP];
+               *lpb++ = color[GCOMP];
+               *lpb++ = color[RCOMP];          
+       }
+}
+
+/* Write an array of RGBA pixels with a boolean mask. */
+static void write_rgba_pixels_24(const GLcontext *ctx, 
+                                struct gl_renderbuffer *rb,
+                                GLuint n, const GLint x[], const GLint y[],
+                                const GLubyte rgba[][4], 
+                                const GLubyte mask[])
+{
+    GLuint i;
+    WMesaContext pwc = wmesa_context(ctx);
+    WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
+    for (i=0; i<n; i++)
+       if (mask[i])
+           WMSETPIXEL24(pwfb, FLIP(y[i]), x[i],
+                        rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
+}
+
+/*
+ * Write an array of pixels with a boolean mask.  The current color
+ * is used for all pixels.
+ */
+static void write_mono_rgba_pixels_24(const GLcontext *ctx, 
+                                     struct gl_renderbuffer *rb,
+                                     GLuint n,
+                                     const GLint x[], const GLint y[],
+                                     const GLchan color[4],
+                                     const GLubyte mask[])
+{
+    GLuint i;
+    WMesaContext pwc = wmesa_context(ctx);
+    WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
+    for (i=0; i<n; i++)
+       if (mask[i])
+           WMSETPIXEL24(pwfb, FLIP(y[i]),x[i],color[RCOMP],
+                        color[GCOMP], color[BCOMP]);
+}
+
+/* Read a horizontal span of color pixels. */
+static void read_rgba_span_24(const GLcontext *ctx, 
+                             struct gl_renderbuffer *rb,
+                             GLuint n, GLint x, GLint y,
+                             GLubyte rgba[][4] )
+{
+    GLuint i;
+    LPBYTE lpb;
+    WMesaContext pwc = wmesa_context(ctx);
+    WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
+    
+    y = FLIP(y);
+    lpb = ((LPBYTE)(pwfb->pbPixels + pwfb->ScanWidth * y)) + (3 * x);
+    for (i=0; i<n; i++) {
+       rgba[i][RCOMP] = lpb[3*i+2];
+       rgba[i][GCOMP] = lpb[3*i+1];
+       rgba[i][BCOMP] = lpb[3*i];
+       rgba[i][ACOMP] = 255;
+    }
+}
+
+
+/* Read an array of color pixels. */
+static void read_rgba_pixels_24(const GLcontext *ctx, 
+                               struct gl_renderbuffer *rb,
+                               GLuint n, const GLint x[], const GLint y[],
+                               GLubyte rgba[][4])
+{
+    GLuint i;
+    LPBYTE lpb;
+    WMesaContext pwc = wmesa_context(ctx);
+    WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
+
+    for (i=0; i<n; i++) {
+       GLint y2 = FLIP(y[i]);
+       lpb = ((LPBYTE)(pwfb->pbPixels + pwfb->ScanWidth * y2)) + (3 * x[i]);
+       rgba[i][RCOMP] = lpb[3*i+2];
+       rgba[i][GCOMP] = lpb[3*i+1];
+       rgba[i][BCOMP] = lpb[3*i];
+       rgba[i][ACOMP] = 255;
+  }
+}
+
+
 /*********************************************************************/
 
 /* DOUBLE BUFFER 16-bit */
@@ -1018,7 +1271,7 @@ wmesa_renderbuffer_storage(GLcontext *ctx,
  * on if we're drawing to the front or back color buffer.
  */
 void wmesa_set_renderbuffer_funcs(struct gl_renderbuffer *rb, int pixelformat,
-                                  int double_buffer)
+                                  BYTE cColorBits, int double_buffer)
 {
     if (double_buffer) {
         /* back buffer */
@@ -1038,16 +1291,32 @@ void wmesa_set_renderbuffer_funcs(struct gl_renderbuffer *rb, int pixelformat,
             rb->BlueBits = 5;
            break;
        case PF_8R8G8B:
-           rb->PutRow = write_rgba_span_32;
-           rb->PutRowRGB = write_rgb_span_32;
-           rb->PutMonoRow = write_mono_rgba_span_32;
-           rb->PutValues = write_rgba_pixels_32;
-           rb->PutMonoValues = write_mono_rgba_pixels_32;
-           rb->GetRow = read_rgba_span_32;
-           rb->GetValues = read_rgba_pixels_32;
+               if (cColorBits == 24)
+               {
+                   rb->PutRow = write_rgba_span_24;
+                   rb->PutRowRGB = write_rgb_span_24;
+                   rb->PutMonoRow = write_mono_rgba_span_24;
+                   rb->PutValues = write_rgba_pixels_24;
+                   rb->PutMonoValues = write_mono_rgba_pixels_24;
+                   rb->GetRow = read_rgba_span_24;
+                   rb->GetValues = read_rgba_pixels_24;
+               rb->RedBits = 8;
+               rb->GreenBits = 8;
+               rb->BlueBits = 8;               
+               }
+               else
+               {
+               rb->PutRow = write_rgba_span_32;
+               rb->PutRowRGB = write_rgb_span_32;
+               rb->PutMonoRow = write_mono_rgba_span_32;
+               rb->PutValues = write_rgba_pixels_32;
+               rb->PutMonoValues = write_mono_rgba_pixels_32;
+               rb->GetRow = read_rgba_span_32;
+               rb->GetValues = read_rgba_pixels_32;
             rb->RedBits = 8;
             rb->GreenBits = 8;
             rb->BlueBits = 8;
+               }
            break;
        default:
            break;
@@ -1128,7 +1397,7 @@ static void wmesa_update_state(GLcontext *ctx, GLuint new_state)
 {
     _swrast_InvalidateState(ctx, new_state);
     _swsetup_InvalidateState(ctx, new_state);
-    _ac_InvalidateState(ctx, new_state);
+    _vbo_InvalidateState(ctx, new_state);
     _tnl_InvalidateState(ctx, new_state);
 
     /* TODO - This code is not complete yet because I 
@@ -1174,7 +1443,7 @@ WMesaContext WMesaCreateContext(HDC hDC,
     /* I do not understand this contributed code */
     /* Support memory and device contexts */
     if(WindowFromDC(hDC) != NULL) {
-       c->hDC = GetDC(WindowFromDC(hDC)); // huh ????
+       c->hDC = GetDC(WindowFromDC(hDC)); /* huh ???? */
     }
     else {
        c->hDC = hDC;
@@ -1237,15 +1506,21 @@ WMesaContext WMesaCreateContext(HDC hDC,
     ctx = &c->gl_ctx;
     _mesa_initialize_context(ctx, visual, NULL, &functions, (void *)c);
 
+    /* visual no longer needed - it was copied by _mesa_initialize_context() */
+    _mesa_destroy_visual(visual);
+
     _mesa_enable_sw_extensions(ctx);
     _mesa_enable_1_3_extensions(ctx);
     _mesa_enable_1_4_extensions(ctx);
     _mesa_enable_1_5_extensions(ctx);
     _mesa_enable_2_0_extensions(ctx);
+    _mesa_enable_2_1_extensions(ctx);
   
+    _mesa_meta_init(ctx);
+
     /* Initialize the software rasterizer and helper modules. */
     if (!_swrast_CreateContext(ctx) ||
-        !_ac_CreateContext(ctx) ||
+        !_vbo_CreateContext(ctx) ||
         !_tnl_CreateContext(ctx) ||
        !_swsetup_CreateContext(ctx)) {
        _mesa_free_context_data(ctx);
@@ -1286,9 +1561,11 @@ void WMesaDestroyContext( WMesaContext pwc )
     DeleteObject(pwc->clearPen); 
     DeleteObject(pwc->clearBrush); 
     
+    _mesa_meta_free(ctx);
+
     _swsetup_DestroyContext(ctx);
     _tnl_DestroyContext(ctx);
-    _ac_DestroyContext(ctx);
+    _vbo_DestroyContext(ctx);
     _swrast_DestroyContext(ctx);
     
     _mesa_free_context_data(ctx);
@@ -1353,11 +1630,11 @@ void WMesaMakeCurrent(WMesaContext c, HDC hdc)
         if (visual->doubleBufferMode == 1) {
             rb = wmesa_new_renderbuffer();
             _mesa_add_renderbuffer(&pwfb->Base, BUFFER_BACK_LEFT, rb);
-            wmesa_set_renderbuffer_funcs(rb, pwfb->pixelformat, 1);
+            wmesa_set_renderbuffer_funcs(rb, pwfb->pixelformat, pwfb->cColorBits, 1);
        }
         rb = wmesa_new_renderbuffer();
         _mesa_add_renderbuffer(&pwfb->Base, BUFFER_FRONT_LEFT, rb);
-        wmesa_set_renderbuffer_funcs(rb, pwfb->pixelformat, 0);
+        wmesa_set_renderbuffer_funcs(rb, pwfb->pixelformat, pwfb->cColorBits, 0);
 
        /* Let Mesa own the Depth, Stencil, and Accum buffers */
         _mesa_add_soft_renderbuffers(&pwfb->Base,
@@ -1402,52 +1679,8 @@ void WMesaSwapBuffers( HDC hdc )
     }
 }
 
-/* This is hopefully a temporary hack to define some needed dispatch
- * table entries.  Hopefully, I'll find a better solution.  The
- * dispatch table generation scripts ought to be making these dummy
- * stubs as well. */
-void gl_dispatch_stub_543(void){};
-void gl_dispatch_stub_544(void){};
-void gl_dispatch_stub_545(void){};
-void gl_dispatch_stub_546(void){};
-void gl_dispatch_stub_547(void){};
-void gl_dispatch_stub_548(void){};
-void gl_dispatch_stub_549(void){};
-void gl_dispatch_stub_550(void){};
-void gl_dispatch_stub_551(void){};
-void gl_dispatch_stub_552(void){};
-void gl_dispatch_stub_553(void){};
-void gl_dispatch_stub_554(void){};
-void gl_dispatch_stub_555(void){};
-void gl_dispatch_stub_556(void){};
-void gl_dispatch_stub_557(void){};
-void gl_dispatch_stub_558(void){};
-void gl_dispatch_stub_559(void){};
-void gl_dispatch_stub_560(void){};
-void gl_dispatch_stub_561(void){};
-void gl_dispatch_stub_565(void){};
-void gl_dispatch_stub_566(void){};
-void gl_dispatch_stub_577(void){};
-void gl_dispatch_stub_578(void){};
-void gl_dispatch_stub_603(void){};
-void gl_dispatch_stub_645(void){};
-void gl_dispatch_stub_646(void){};
-void gl_dispatch_stub_647(void){};
-void gl_dispatch_stub_648(void){};
-void gl_dispatch_stub_649(void){};
-void gl_dispatch_stub_650(void){};
-void gl_dispatch_stub_651(void){};
-void gl_dispatch_stub_652(void){};
-void gl_dispatch_stub_653(void){};
-void gl_dispatch_stub_734(void){};
-void gl_dispatch_stub_735(void){};
-void gl_dispatch_stub_736(void){};
-void gl_dispatch_stub_737(void){};
-void gl_dispatch_stub_738(void){};
-void gl_dispatch_stub_745(void){};
-void gl_dispatch_stub_746(void){};
-void gl_dispatch_stub_760(void){};
-void gl_dispatch_stub_761(void){};
-void gl_dispatch_stub_766(void){};
-void gl_dispatch_stub_767(void){};
-void gl_dispatch_stub_768(void){};
+void WMesaShareLists(WMesaContext ctx_to_share, WMesaContext ctx)
+{
+       _mesa_share_state(&ctx->gl_ctx, &ctx_to_share->gl_ctx); 
+}
+