ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

wmesa.c
Go to the documentation of this file.
00001 /*
00002  * Windows (Win32/Win64) device driver for Mesa
00003  *
00004  */
00005 
00006 #include "wmesadef.h"
00007 #include "colors.h"
00008 #include <GL/wmesa.h>
00009 #include <winuser.h>
00010 #include "context.h"
00011 #include "extensions.h"
00012 #include "framebuffer.h"
00013 #include "renderbuffer.h"
00014 #include "drivers/common/driverfuncs.h"
00015 #include "vbo/vbo.h"
00016 #include "swrast/swrast.h"
00017 #include "swrast_setup/swrast_setup.h"
00018 #include "tnl/tnl.h"
00019 #include "tnl/t_context.h"
00020 #include "tnl/t_pipeline.h"
00021 
00022 
00023 /* linked list of our Framebuffers (windows) */
00024 static WMesaFramebuffer FirstFramebuffer = NULL;
00025 
00026 
00031 WMesaFramebuffer
00032 wmesa_new_framebuffer(HDC hdc, GLvisual *visual)
00033 {
00034     WMesaFramebuffer pwfb
00035         = (WMesaFramebuffer) malloc(sizeof(struct wmesa_framebuffer));
00036     if (pwfb) {
00037         _mesa_initialize_framebuffer(&pwfb->Base, visual);
00038         pwfb->hDC = hdc;
00039         /* insert at head of list */
00040         pwfb->next = FirstFramebuffer;
00041         FirstFramebuffer = pwfb;
00042     }
00043     return pwfb;
00044 }
00045 
00049 void
00050 wmesa_free_framebuffer(HDC hdc)
00051 {
00052     WMesaFramebuffer pwfb, prev;
00053     for (pwfb = FirstFramebuffer; pwfb; pwfb = pwfb->next) {
00054         if (pwfb->hDC == hdc)
00055             break;
00056     prev = pwfb;
00057     }
00058     if (pwfb) {
00059         struct gl_framebuffer *fb;
00060     if (pwfb == FirstFramebuffer)
00061         FirstFramebuffer = pwfb->next;
00062     else
00063         prev->next = pwfb->next;
00064         fb = &pwfb->Base;
00065         _mesa_unreference_framebuffer(&fb); 
00066     }
00067 }
00068 
00072 WMesaFramebuffer
00073 wmesa_lookup_framebuffer(HDC hdc)
00074 {
00075     WMesaFramebuffer pwfb;
00076     for (pwfb = FirstFramebuffer; pwfb; pwfb = pwfb->next) {
00077         if (pwfb->hDC == hdc)
00078             return pwfb;
00079     }
00080     return NULL;
00081 }
00082 
00083 
00087 static WMesaFramebuffer wmesa_framebuffer(GLframebuffer *fb)
00088 {
00089     return (WMesaFramebuffer) fb;
00090 }
00091 
00092 
00096 static WMesaContext wmesa_context(const GLcontext *ctx)
00097 {
00098     return (WMesaContext) ctx;
00099 }
00100 
00101 
00102 /*
00103  * Every driver should implement a GetString function in order to
00104  * return a meaningful GL_RENDERER string.
00105  */
00106 static const GLubyte *wmesa_get_string(GLcontext *ctx, GLenum name)
00107 {
00108     return (name == GL_RENDERER) ? 
00109     (GLubyte *) "Mesa Windows GDI Driver" : NULL;
00110 }
00111 
00112 
00113 /*
00114  * Determine the pixel format based on the pixel size.
00115  */
00116 static void wmSetPixelFormat(WMesaFramebuffer pwfb, HDC hDC)
00117 {
00118     pwfb->cColorBits = GetDeviceCaps(hDC, BITSPIXEL);
00119 
00120     /* Only 16 and 32 bit targets are supported now */
00121     assert(pwfb->cColorBits == 0 ||
00122        pwfb->cColorBits == 16 || 
00123        pwfb->cColorBits == 24 || 
00124        pwfb->cColorBits == 32);
00125 
00126     switch(pwfb->cColorBits){
00127     case 8:
00128     pwfb->pixelformat = PF_INDEX8;
00129     break;
00130     case 16:
00131     pwfb->pixelformat = PF_5R6G5B;
00132     break;
00133     case 24:
00134     case 32:
00135     pwfb->pixelformat = PF_8R8G8B;
00136     break;
00137     default:
00138     pwfb->pixelformat = PF_BADFORMAT;
00139     }
00140 }
00141 
00142 
00148 BOOL wmCreateBackingStore(WMesaFramebuffer pwfb, long lxSize, long lySize)
00149 {
00150     HDC          hdc = pwfb->hDC;
00151     LPBITMAPINFO pbmi = &(pwfb->bmi);
00152     HDC          hic;
00153 
00154     pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
00155     pbmi->bmiHeader.biWidth = lxSize;
00156     pbmi->bmiHeader.biHeight= -lySize;
00157     pbmi->bmiHeader.biPlanes = 1;
00158     pbmi->bmiHeader.biBitCount = GetDeviceCaps(pwfb->hDC, BITSPIXEL);
00159     pbmi->bmiHeader.biCompression = BI_RGB;
00160     pbmi->bmiHeader.biSizeImage = 0;
00161     pbmi->bmiHeader.biXPelsPerMeter = 0;
00162     pbmi->bmiHeader.biYPelsPerMeter = 0;
00163     pbmi->bmiHeader.biClrUsed = 0;
00164     pbmi->bmiHeader.biClrImportant = 0;
00165     
00166     pwfb->cColorBits = pbmi->bmiHeader.biBitCount;
00167     pwfb->ScanWidth = (lxSize * (pwfb->cColorBits / 8) + 3) & ~3;
00168     
00169     hic = CreateIC("display", NULL, NULL, NULL);
00170     pwfb->dib_hDC = CreateCompatibleDC(hic);
00171     
00172     pwfb->hbmDIB = CreateDIBSection(hic,
00173                    &pwfb->bmi,
00174                    DIB_RGB_COLORS,
00175                    (void **)&(pwfb->pbPixels),
00176                    0,
00177                    0);
00178     pwfb->hOldBitmap = SelectObject(pwfb->dib_hDC, pwfb->hbmDIB);
00179     
00180     DeleteDC(hic);
00181 
00182     wmSetPixelFormat(pwfb, pwfb->hDC);
00183     return TRUE;
00184 }
00185 
00186 
00187 static wmDeleteBackingStore(WMesaFramebuffer pwfb)
00188 {
00189     if (pwfb->hbmDIB) {
00190     SelectObject(pwfb->dib_hDC, pwfb->hOldBitmap);
00191     DeleteDC(pwfb->dib_hDC);
00192     DeleteObject(pwfb->hbmDIB);
00193     }
00194 }
00195 
00196 
00200 static void
00201 get_window_size(HDC hdc, GLuint *width, GLuint *height)
00202 {
00203     if (WindowFromDC(hdc)) {
00204         RECT rect;
00205         GetClientRect(WindowFromDC(hdc), &rect);
00206         *width = rect.right - rect.left;
00207         *height = rect.bottom - rect.top;
00208     }
00209     else { /* Memory context */
00210         /* From contributed code - use the size of the desktop
00211          * for the size of a memory context (?) */
00212         *width = GetDeviceCaps(hdc, HORZRES);
00213         *height = GetDeviceCaps(hdc, VERTRES);
00214     }
00215 }
00216 
00217 
00218 static void
00219 wmesa_get_buffer_size(GLframebuffer *buffer, GLuint *width, GLuint *height)
00220 {
00221     WMesaFramebuffer pwfb = wmesa_framebuffer(buffer);
00222     get_window_size(pwfb->hDC, width, height);
00223 }
00224 
00225 
00226 static void wmesa_flush(GLcontext *ctx)
00227 {
00228     WMesaContext pwc = wmesa_context(ctx);
00229     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->WinSysDrawBuffer);
00230 
00231     if (ctx->Visual.doubleBufferMode == 1) {
00232     BitBlt(pwfb->hDC, 0, 0, pwfb->Base.Width, pwfb->Base.Height,
00233            pwfb->dib_hDC, 0, 0, SRCCOPY);
00234     }
00235     else {
00236     /* Do nothing for single buffer */
00237     }
00238 }
00239 
00240 
00241 /**********************************************************************/
00242 /*****                   CLEAR Functions                          *****/
00243 /**********************************************************************/
00244 
00245 /* If we do not implement these, Mesa clears the buffers via the pixel
00246  * span writing interface, which is very slow for a clear operation.
00247  */
00248 
00249 /*
00250  * Set the color index used to clear the color buffer.
00251  */
00252 static void clear_index(GLcontext *ctx, GLuint index)
00253 {
00254     WMesaContext pwc = wmesa_context(ctx);
00255     /* Note that indexed mode is not supported yet */
00256     pwc->clearColorRef = RGB(0,0,0);
00257 }
00258 
00259 /*
00260  * Set the color used to clear the color buffer.
00261  */
00262 static void clear_color(GLcontext *ctx, const GLfloat color[4])
00263 {
00264     WMesaContext pwc = wmesa_context(ctx);
00265     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
00266     GLubyte col[3];
00267     UINT    bytesPerPixel = pwfb->cColorBits / 8; 
00268 
00269     CLAMPED_FLOAT_TO_UBYTE(col[0], color[0]);
00270     CLAMPED_FLOAT_TO_UBYTE(col[1], color[1]);
00271     CLAMPED_FLOAT_TO_UBYTE(col[2], color[2]);
00272     pwc->clearColorRef = RGB(col[0], col[1], col[2]);
00273     DeleteObject(pwc->clearPen);
00274     DeleteObject(pwc->clearBrush);
00275     pwc->clearPen = CreatePen(PS_SOLID, 1, pwc->clearColorRef); 
00276     pwc->clearBrush = CreateSolidBrush(pwc->clearColorRef); 
00277 }
00278 
00279 
00280 /* 
00281  * Clear the specified region of the color buffer using the clear color 
00282  * or index as specified by one of the two functions above. 
00283  * 
00284  * This procedure clears either the front and/or the back COLOR buffers. 
00285  * Only the "left" buffer is cleared since we are not stereo. 
00286  * Clearing of the other non-color buffers is left to the swrast. 
00287  */ 
00288 
00289 static void clear(GLcontext *ctx, GLbitfield mask)
00290 {
00291 #define FLIP(Y)  (ctx->DrawBuffer->Height - (Y) - 1)
00292     const GLint x = ctx->DrawBuffer->_Xmin;
00293     const GLint y = ctx->DrawBuffer->_Ymin;
00294     const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
00295     const GLint width  = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
00296 
00297     WMesaContext pwc = wmesa_context(ctx);
00298     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
00299     int done = 0;
00300 
00301     /* Let swrast do all the work if the masks are not set to
00302      * clear all channels. */
00303     if (ctx->Color.ColorMask[0] != 0xff ||
00304     ctx->Color.ColorMask[1] != 0xff ||
00305     ctx->Color.ColorMask[2] != 0xff ||
00306     ctx->Color.ColorMask[3] != 0xff) {
00307     _swrast_Clear(ctx, mask);
00308     return;
00309     }
00310 
00311     /* Back buffer */
00312     if (mask & BUFFER_BIT_BACK_LEFT) { 
00313     
00314     int     i, rowSize; 
00315     UINT    bytesPerPixel = pwfb->cColorBits / 8; 
00316     LPBYTE  lpb, clearRow;
00317     LPWORD  lpw;
00318     BYTE    bColor; 
00319     WORD    wColor; 
00320     BYTE    r, g, b; 
00321     DWORD   dwColor; 
00322     LPDWORD lpdw; 
00323     
00324     /* Try for a fast clear - clearing entire buffer with a single
00325      * byte value. */
00326     if (width == ctx->DrawBuffer->Width &&
00327             height == ctx->DrawBuffer->Height) { /* entire buffer */
00328         /* Now check for an easy clear value */
00329         switch (bytesPerPixel) {
00330         case 1:
00331         bColor = BGR8(GetRValue(pwc->clearColorRef), 
00332                   GetGValue(pwc->clearColorRef), 
00333                   GetBValue(pwc->clearColorRef));
00334         memset(pwfb->pbPixels, bColor, 
00335                pwfb->ScanWidth * height);
00336         done = 1;
00337         break;
00338         case 2:
00339         wColor = BGR16(GetRValue(pwc->clearColorRef), 
00340                    GetGValue(pwc->clearColorRef), 
00341                    GetBValue(pwc->clearColorRef)); 
00342         if (((wColor >> 8) & 0xff) == (wColor & 0xff)) {
00343             memset(pwfb->pbPixels, wColor & 0xff, 
00344                pwfb->ScanWidth * height);
00345             done = 1;
00346         }
00347         break;
00348         case 3:
00349         /* fall through */
00350         case 4:
00351         if (GetRValue(pwc->clearColorRef) == 
00352             GetGValue(pwc->clearColorRef) &&
00353             GetRValue(pwc->clearColorRef) == 
00354             GetBValue(pwc->clearColorRef)) {
00355             memset(pwfb->pbPixels, 
00356                GetRValue(pwc->clearColorRef), 
00357                pwfb->ScanWidth * height);
00358             done = 1;
00359         }
00360         break;
00361         default:
00362         break;
00363         }
00364     } /* all */
00365 
00366     if (!done) {
00367         /* Need to clear a row at a time.  Begin by setting the first
00368          * row in the area to be cleared to the clear color. */
00369         
00370         clearRow = pwfb->pbPixels + 
00371         pwfb->ScanWidth * FLIP(y) +
00372         bytesPerPixel * x; 
00373         switch (bytesPerPixel) {
00374         case 1:
00375         lpb = clearRow;
00376         bColor = BGR8(GetRValue(pwc->clearColorRef), 
00377                   GetGValue(pwc->clearColorRef), 
00378                   GetBValue(pwc->clearColorRef));
00379         memset(lpb, bColor, width);
00380         break;
00381         case 2:
00382         lpw = (LPWORD)clearRow;
00383         wColor = BGR16(GetRValue(pwc->clearColorRef), 
00384                    GetGValue(pwc->clearColorRef), 
00385                    GetBValue(pwc->clearColorRef)); 
00386         for (i=0; i<width; i++)
00387             *lpw++ = wColor;
00388         break;
00389         case 3: 
00390         lpb = clearRow;
00391         r = GetRValue(pwc->clearColorRef); 
00392         g = GetGValue(pwc->clearColorRef); 
00393         b = GetBValue(pwc->clearColorRef); 
00394         for (i=0; i<width; i++) {
00395             *lpb++ = b; 
00396             *lpb++ = g; 
00397             *lpb++ = r; 
00398         } 
00399         break;
00400         case 4: 
00401         lpdw = (LPDWORD)clearRow; 
00402         dwColor = BGR32(GetRValue(pwc->clearColorRef), 
00403                 GetGValue(pwc->clearColorRef), 
00404                 GetBValue(pwc->clearColorRef)); 
00405         for (i=0; i<width; i++)
00406             *lpdw++ = dwColor;
00407         break;
00408         default:
00409         break;
00410         } /* switch */
00411         
00412         /* copy cleared row to other rows in buffer */
00413         lpb = clearRow - pwfb->ScanWidth;
00414         rowSize = width * bytesPerPixel;
00415         for (i=1; i<height; i++) { 
00416         memcpy(lpb, clearRow, rowSize); 
00417         lpb -= pwfb->ScanWidth; 
00418         } 
00419     } /* not done */
00420     mask &= ~BUFFER_BIT_BACK_LEFT;
00421     } /* back buffer */ 
00422 
00423     /* front buffer */
00424     if (mask & BUFFER_BIT_FRONT_LEFT) { 
00425     HDC DC = pwc->hDC; 
00426     HPEN Old_Pen = SelectObject(DC, pwc->clearPen); 
00427     HBRUSH Old_Brush = SelectObject(DC, pwc->clearBrush);
00428     Rectangle(DC,
00429           x,
00430           FLIP(y) + 1,
00431           x + width + 1,
00432           FLIP(y) - height + 1);
00433     SelectObject(DC, Old_Pen); 
00434     SelectObject(DC, Old_Brush); 
00435     mask &= ~BUFFER_BIT_FRONT_LEFT;
00436     } /* front buffer */ 
00437     
00438     /* Call swrast if there is anything left to clear (like DEPTH) */ 
00439     if (mask) 
00440     _swrast_Clear(ctx, mask);
00441   
00442 #undef FLIP
00443 } 
00444 
00445 
00446 /**********************************************************************/
00447 /*****                   PIXEL Functions                          *****/
00448 /**********************************************************************/
00449 
00450 #define FLIP(Y)  (rb->Height - (Y) - 1)
00451 
00452 
00458 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
00459 static void write_rgba_span_front(const GLcontext *ctx, 
00460                    struct gl_renderbuffer *rb, 
00461                    GLuint n, GLint x, GLint y,
00462                    const GLubyte rgba[][4], 
00463                    const GLubyte mask[] )
00464 {
00465    WMesaContext pwc = wmesa_context(ctx);
00466    WMesaFramebuffer pwfb = wmesa_lookup_framebuffer(pwc->hDC);
00467    CONST BITMAPINFO bmi=
00468    {
00469       {
00470          sizeof(BITMAPINFOHEADER),
00471          n, 1, 1, 32, BI_RGB, 0, 1, 1, 0, 0
00472       }
00473    };
00474    HBITMAP bmp=0;
00475    HDC mdc=0;
00476    typedef union
00477    {
00478       unsigned i;
00479       struct {
00480          unsigned b:8, g:8, r:8, a:8;
00481       };
00482    } BGRA;
00483    BGRA *bgra, c;
00484    int i;
00485 
00486    if (n < 16) {   // the value 16 is just guessed
00487       y=FLIP(y);
00488       if (mask) {
00489          for (i=0; i<n; i++)
00490             if (mask[i])
00491                SetPixel(pwc->hDC, x+i, y,
00492                         RGB(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]));
00493       }
00494       else {
00495          for (i=0; i<n; i++)
00496             SetPixel(pwc->hDC, x+i, y,
00497                      RGB(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]));
00498       }
00499    }
00500    else {
00501       if (!pwfb) {
00502          _mesa_problem(NULL, "wmesa: write_rgba_span_front on unknown hdc");
00503          return;
00504       }
00505       bgra=malloc(n*sizeof(BGRA));
00506       if (!bgra) {
00507          _mesa_problem(NULL, "wmesa: write_rgba_span_front: out of memory");
00508          return;
00509       }
00510       c.a=0;
00511       if (mask) {
00512          for (i=0; i<n; i++) {
00513             if (mask[i]) {
00514                c.r=rgba[i][RCOMP];
00515                c.g=rgba[i][GCOMP];
00516                c.b=rgba[i][BCOMP];
00517                c.a=rgba[i][ACOMP];
00518                bgra[i]=c;
00519             }
00520             else
00521                bgra[i].i=0;
00522          }
00523       }
00524       else {
00525          for (i=0; i<n; i++) {
00526             c.r=rgba[i][RCOMP];
00527             c.g=rgba[i][GCOMP];
00528             c.b=rgba[i][BCOMP];
00529             c.a=rgba[i][ACOMP];
00530             bgra[i]=c;
00531          }
00532       }
00533       bmp=CreateBitmap(n, 1,  1, 32, bgra);
00534       mdc=CreateCompatibleDC(pwfb->hDC);
00535       SelectObject(mdc, bmp);
00536       y=FLIP(y);
00537       BitBlt(pwfb->hDC, x, y, n, 1, mdc, 0, 0, SRCCOPY);
00538       SelectObject(mdc, 0);
00539       DeleteObject(bmp);
00540       DeleteDC(mdc);
00541       free(bgra);
00542    }
00543 }
00544 
00545 /* Write a horizontal span of RGB color pixels with a boolean mask. */
00546 static void write_rgb_span_front(const GLcontext *ctx, 
00547                   struct gl_renderbuffer *rb, 
00548                   GLuint n, GLint x, GLint y,
00549                   const GLubyte rgb[][3], 
00550                   const GLubyte mask[] )
00551 {
00552     WMesaContext pwc = wmesa_context(ctx);
00553     GLuint i;
00554     
00555     (void) ctx;
00556     y=FLIP(y);
00557     if (mask) {
00558     for (i=0; i<n; i++)
00559         if (mask[i])
00560         SetPixel(pwc->hDC, x+i, y, RGB(rgb[i][RCOMP], rgb[i][GCOMP], 
00561                            rgb[i][BCOMP]));
00562     }
00563     else {
00564     for (i=0; i<n; i++)
00565         SetPixel(pwc->hDC, x+i, y, RGB(rgb[i][RCOMP], rgb[i][GCOMP], 
00566                        rgb[i][BCOMP]));
00567     }
00568     
00569 }
00570 
00571 /*
00572  * Write a horizontal span of pixels with a boolean mask.  The current color
00573  * is used for all pixels.
00574  */
00575 static void write_mono_rgba_span_front(const GLcontext *ctx, 
00576                     struct gl_renderbuffer *rb,
00577                     GLuint n, GLint x, GLint y,
00578                     const GLchan color[4], 
00579                     const GLubyte mask[])
00580 {
00581     GLuint i;
00582     WMesaContext pwc = wmesa_context(ctx);
00583     COLORREF colorref;
00584 
00585     (void) ctx;
00586     colorref = RGB(color[RCOMP], color[GCOMP], color[BCOMP]);
00587     y=FLIP(y);
00588     if (mask) {
00589     for (i=0; i<n; i++)
00590         if (mask[i])
00591         SetPixel(pwc->hDC, x+i, y, colorref);
00592     }
00593     else
00594     for (i=0; i<n; i++)
00595         SetPixel(pwc->hDC, x+i, y, colorref);
00596 
00597 }
00598 
00599 /* Write an array of RGBA pixels with a boolean mask. */
00600 static void write_rgba_pixels_front(const GLcontext *ctx, 
00601                      struct gl_renderbuffer *rb,
00602                      GLuint n, 
00603                      const GLint x[], const GLint y[],
00604                      const GLubyte rgba[][4], 
00605                      const GLubyte mask[] )
00606 {
00607     GLuint i;
00608     WMesaContext pwc = wmesa_context(ctx);
00609     (void) ctx;
00610     for (i=0; i<n; i++)
00611     if (mask[i])
00612         SetPixel(pwc->hDC, x[i], FLIP(y[i]), 
00613              RGB(rgba[i][RCOMP], rgba[i][GCOMP], 
00614              rgba[i][BCOMP]));
00615 }
00616 
00617 
00618 
00619 /*
00620  * Write an array of pixels with a boolean mask.  The current color
00621  * is used for all pixels.
00622  */
00623 static void write_mono_rgba_pixels_front(const GLcontext *ctx, 
00624                       struct gl_renderbuffer *rb,
00625                       GLuint n,
00626                       const GLint x[], const GLint y[],
00627                       const GLchan color[4],
00628                       const GLubyte mask[] )
00629 {
00630     GLuint i;
00631     WMesaContext pwc = wmesa_context(ctx);
00632     COLORREF colorref;
00633     (void) ctx;
00634     colorref = RGB(color[RCOMP], color[GCOMP], color[BCOMP]);
00635     for (i=0; i<n; i++)
00636     if (mask[i])
00637         SetPixel(pwc->hDC, x[i], FLIP(y[i]), colorref);
00638 }
00639 
00640 /* Read a horizontal span of color pixels. */
00641 static void read_rgba_span_front(const GLcontext *ctx, 
00642                   struct gl_renderbuffer *rb,
00643                   GLuint n, GLint x, GLint y,
00644                   GLubyte rgba[][4] )
00645 {
00646     WMesaContext pwc = wmesa_context(ctx);
00647     GLuint i;
00648     COLORREF Color;
00649     y = FLIP(y);
00650     for (i=0; i<n; i++) {
00651     Color = GetPixel(pwc->hDC, x+i, y);
00652     rgba[i][RCOMP] = GetRValue(Color);
00653     rgba[i][GCOMP] = GetGValue(Color);
00654     rgba[i][BCOMP] = GetBValue(Color);
00655     rgba[i][ACOMP] = 255;
00656     }
00657 }
00658 
00659 
00660 /* Read an array of color pixels. */
00661 static void read_rgba_pixels_front(const GLcontext *ctx, 
00662                     struct gl_renderbuffer *rb,
00663                     GLuint n, const GLint x[], const GLint y[],
00664                     GLubyte rgba[][4])
00665 {
00666     WMesaContext pwc = wmesa_context(ctx);
00667     GLuint i;
00668     COLORREF Color;
00669     for (i=0; i<n; i++) {
00670         GLint y2 = FLIP(y[i]);
00671         Color = GetPixel(pwc->hDC, x[i], y2);
00672         rgba[i][RCOMP] = GetRValue(Color);
00673         rgba[i][GCOMP] = GetGValue(Color);
00674         rgba[i][BCOMP] = GetBValue(Color);
00675         rgba[i][ACOMP] = 255;
00676     }
00677 }
00678 
00679 /*********************************************************************/
00680 
00681 /* DOUBLE BUFFER 32-bit */
00682 
00683 #define WMSETPIXEL32(pwc, y, x, r, g, b) { \
00684 LPDWORD lpdw = ((LPDWORD)((pwc)->pbPixels + (pwc)->ScanWidth * (y)) + (x)); \
00685 *lpdw = BGR32((r),(g),(b)); }
00686 
00687 
00688 
00689 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
00690 static void write_rgba_span_32(const GLcontext *ctx, 
00691                    struct gl_renderbuffer *rb, 
00692                    GLuint n, GLint x, GLint y,
00693                    const GLubyte rgba[][4], 
00694                    const GLubyte mask[] )
00695 {
00696     WMesaContext pwc = wmesa_context(ctx);
00697     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
00698     GLuint i;
00699     LPDWORD lpdw;
00700 
00701     (void) ctx;
00702     
00703     y=FLIP(y);
00704     lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x;
00705     if (mask) {
00706     for (i=0; i<n; i++)
00707         if (mask[i])
00708                 lpdw[i] = BGR32(rgba[i][RCOMP], rgba[i][GCOMP], 
00709                 rgba[i][BCOMP]);
00710     }
00711     else {
00712     for (i=0; i<n; i++)
00713                 *lpdw++ = BGR32(rgba[i][RCOMP], rgba[i][GCOMP], 
00714                 rgba[i][BCOMP]);
00715     }
00716 }
00717 
00718 
00719 /* Write a horizontal span of RGB color pixels with a boolean mask. */
00720 static void write_rgb_span_32(const GLcontext *ctx, 
00721                   struct gl_renderbuffer *rb, 
00722                   GLuint n, GLint x, GLint y,
00723                   const GLubyte rgb[][3], 
00724                   const GLubyte mask[] )
00725 {
00726     WMesaContext pwc = wmesa_context(ctx);
00727     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
00728     GLuint i;
00729     LPDWORD lpdw;
00730 
00731     (void) ctx;
00732     
00733     y=FLIP(y);
00734     lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x;
00735     if (mask) {
00736     for (i=0; i<n; i++)
00737         if (mask[i])
00738                 lpdw[i] = BGR32(rgb[i][RCOMP], rgb[i][GCOMP], 
00739                 rgb[i][BCOMP]);
00740     }
00741     else {
00742     for (i=0; i<n; i++)
00743                 *lpdw++ = BGR32(rgb[i][RCOMP], rgb[i][GCOMP], 
00744                 rgb[i][BCOMP]);
00745     }
00746 }
00747 
00748 /*
00749  * Write a horizontal span of pixels with a boolean mask.  The current color
00750  * is used for all pixels.
00751  */
00752 static void write_mono_rgba_span_32(const GLcontext *ctx, 
00753                     struct gl_renderbuffer *rb,
00754                     GLuint n, GLint x, GLint y,
00755                     const GLchan color[4], 
00756                     const GLubyte mask[])
00757 {
00758     LPDWORD lpdw;
00759     DWORD pixel;
00760     GLuint i;
00761     WMesaContext pwc = wmesa_context(ctx);
00762     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
00763     lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x;
00764     y=FLIP(y);
00765     pixel = BGR32(color[RCOMP], color[GCOMP], color[BCOMP]);
00766     if (mask) {
00767     for (i=0; i<n; i++)
00768         if (mask[i])
00769                 lpdw[i] = pixel;
00770     }
00771     else
00772     for (i=0; i<n; i++)
00773                 *lpdw++ = pixel;
00774 
00775 }
00776 
00777 /* Write an array of RGBA pixels with a boolean mask. */
00778 static void write_rgba_pixels_32(const GLcontext *ctx, 
00779                  struct gl_renderbuffer *rb,
00780                  GLuint n, const GLint x[], const GLint y[],
00781                  const GLubyte rgba[][4], 
00782                  const GLubyte mask[])
00783 {
00784     GLuint i;
00785     WMesaContext pwc = wmesa_context(ctx);
00786     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
00787     for (i=0; i<n; i++)
00788     if (mask[i])
00789         WMSETPIXEL32(pwfb, FLIP(y[i]), x[i],
00790              rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
00791 }
00792 
00793 /*
00794  * Write an array of pixels with a boolean mask.  The current color
00795  * is used for all pixels.
00796  */
00797 static void write_mono_rgba_pixels_32(const GLcontext *ctx, 
00798                       struct gl_renderbuffer *rb,
00799                       GLuint n,
00800                       const GLint x[], const GLint y[],
00801                       const GLchan color[4],
00802                       const GLubyte mask[])
00803 {
00804     GLuint i;
00805     WMesaContext pwc = wmesa_context(ctx);
00806     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
00807     for (i=0; i<n; i++)
00808     if (mask[i])
00809         WMSETPIXEL32(pwfb, FLIP(y[i]),x[i],color[RCOMP],
00810              color[GCOMP], color[BCOMP]);
00811 }
00812 
00813 /* Read a horizontal span of color pixels. */
00814 static void read_rgba_span_32(const GLcontext *ctx, 
00815                   struct gl_renderbuffer *rb,
00816                   GLuint n, GLint x, GLint y,
00817                   GLubyte rgba[][4] )
00818 {
00819     GLuint i;
00820     DWORD pixel;
00821     LPDWORD lpdw;
00822     WMesaContext pwc = wmesa_context(ctx);
00823     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
00824     
00825     y = FLIP(y);
00826     lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x;
00827     for (i=0; i<n; i++) {
00828     pixel = lpdw[i];
00829     rgba[i][RCOMP] = (pixel & 0x00ff0000) >> 16;
00830     rgba[i][GCOMP] = (pixel & 0x0000ff00) >> 8;
00831     rgba[i][BCOMP] = (pixel & 0x000000ff);
00832     rgba[i][ACOMP] = 255;
00833     }
00834 }
00835 
00836 
00837 /* Read an array of color pixels. */
00838 static void read_rgba_pixels_32(const GLcontext *ctx, 
00839                 struct gl_renderbuffer *rb,
00840                 GLuint n, const GLint x[], const GLint y[],
00841                 GLubyte rgba[][4])
00842 {
00843     GLuint i;
00844     DWORD pixel;
00845     LPDWORD lpdw;
00846     WMesaContext pwc = wmesa_context(ctx);
00847     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
00848 
00849     for (i=0; i<n; i++) {
00850     GLint y2 = FLIP(y[i]);
00851     lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y2)) + x[i];
00852     pixel = *lpdw;
00853     rgba[i][RCOMP] = (pixel & 0x00ff0000) >> 16;
00854     rgba[i][GCOMP] = (pixel & 0x0000ff00) >> 8;
00855     rgba[i][BCOMP] = (pixel & 0x000000ff);
00856     rgba[i][ACOMP] = 255;
00857   }
00858 }
00859 
00860 
00861 /*********************************************************************/
00862 
00863 /* DOUBLE BUFFER 24-bit */
00864 
00865 #define WMSETPIXEL24(pwc, y, x, r, g, b) { \
00866 LPBYTE lpb = ((LPBYTE)((pwc)->pbPixels + (pwc)->ScanWidth * (y)) + (3 * x)); \
00867 lpb[0] = (b); \
00868 lpb[1] = (g); \
00869 lpb[2] = (r); }
00870 
00871 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
00872 static void write_rgba_span_24(const GLcontext *ctx, 
00873                    struct gl_renderbuffer *rb, 
00874                    GLuint n, GLint x, GLint y,
00875                    const GLubyte rgba[][4], 
00876                    const GLubyte mask[] )
00877 {
00878     WMesaContext pwc = wmesa_context(ctx);
00879     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
00880     GLuint i;
00881     LPBYTE lpb;
00882 
00883     (void) ctx;
00884     
00885     y=FLIP(y);
00886     lpb = ((LPBYTE)(pwfb->pbPixels + pwfb->ScanWidth * y)) + (3 * x);
00887     if (mask) {
00888     for (i=0; i<n; i++)
00889         if (mask[i]) {
00890                 lpb[3*i] = rgba[i][BCOMP];
00891                 lpb[3*i+1] = rgba[i][GCOMP];
00892                 lpb[3*i+2] = rgba[i][RCOMP];
00893         }
00894     }
00895     else {
00896         for (i=0; i<n; i++) {
00897             *lpb++ = rgba[i][BCOMP];
00898             *lpb++ = rgba[i][GCOMP];
00899             *lpb++ = rgba[i][RCOMP];
00900         }
00901     }
00902 }
00903 
00904 
00905 /* Write a horizontal span of RGB color pixels with a boolean mask. */
00906 static void write_rgb_span_24(const GLcontext *ctx, 
00907                   struct gl_renderbuffer *rb, 
00908                   GLuint n, GLint x, GLint y,
00909                   const GLubyte rgb[][3], 
00910                   const GLubyte mask[] )
00911 {
00912     WMesaContext pwc = wmesa_context(ctx);
00913     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
00914     GLuint i;
00915     LPBYTE lpb;
00916 
00917     (void) ctx;
00918     
00919     y=FLIP(y);
00920     lpb = ((LPBYTE)(pwfb->pbPixels + pwfb->ScanWidth * y)) + (3 * x);
00921     if (mask) {
00922     for (i=0; i<n; i++)
00923         if (mask[i]) {
00924             lpb[3*i] = rgb[i][BCOMP];
00925             lpb[3*i+1] = rgb[i][GCOMP];
00926             lpb[3*i+2] = rgb[i][RCOMP];
00927         }
00928     }
00929     else {
00930         for (i=0; i<n; i++) {
00931             *lpb++ = rgb[i][BCOMP];
00932             *lpb++ = rgb[i][GCOMP];
00933             *lpb++ = rgb[i][RCOMP];
00934         }
00935     }
00936 }
00937 
00938 /*
00939  * Write a horizontal span of pixels with a boolean mask.  The current color
00940  * is used for all pixels.
00941  */
00942 static void write_mono_rgba_span_24(const GLcontext *ctx, 
00943                     struct gl_renderbuffer *rb,
00944                     GLuint n, GLint x, GLint y,
00945                     const GLchan color[4], 
00946                     const GLubyte mask[])
00947 {
00948     LPBYTE lpb;
00949     GLuint i;
00950     WMesaContext pwc = wmesa_context(ctx);
00951     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
00952     lpb = ((LPBYTE)(pwfb->pbPixels + pwfb->ScanWidth * y)) + (3 * x);
00953     y=FLIP(y);
00954     if (mask) {
00955     for (i=0; i<n; i++)
00956         if (mask[i]) {
00957             lpb[3*i] = color[BCOMP];
00958             lpb[3*i+1] = color[GCOMP];
00959             lpb[3*i+2] = color[RCOMP];
00960         }
00961     }
00962     else
00963     for (i=0; i<n; i++) {
00964         *lpb++ = color[BCOMP];
00965         *lpb++ = color[GCOMP];
00966         *lpb++ = color[RCOMP];      
00967     }
00968 }
00969 
00970 /* Write an array of RGBA pixels with a boolean mask. */
00971 static void write_rgba_pixels_24(const GLcontext *ctx, 
00972                  struct gl_renderbuffer *rb,
00973                  GLuint n, const GLint x[], const GLint y[],
00974                  const GLubyte rgba[][4], 
00975                  const GLubyte mask[])
00976 {
00977     GLuint i;
00978     WMesaContext pwc = wmesa_context(ctx);
00979     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
00980     for (i=0; i<n; i++)
00981     if (mask[i])
00982         WMSETPIXEL24(pwfb, FLIP(y[i]), x[i],
00983              rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
00984 }
00985 
00986 /*
00987  * Write an array of pixels with a boolean mask.  The current color
00988  * is used for all pixels.
00989  */
00990 static void write_mono_rgba_pixels_24(const GLcontext *ctx, 
00991                       struct gl_renderbuffer *rb,
00992                       GLuint n,
00993                       const GLint x[], const GLint y[],
00994                       const GLchan color[4],
00995                       const GLubyte mask[])
00996 {
00997     GLuint i;
00998     WMesaContext pwc = wmesa_context(ctx);
00999     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
01000     for (i=0; i<n; i++)
01001     if (mask[i])
01002         WMSETPIXEL24(pwfb, FLIP(y[i]),x[i],color[RCOMP],
01003              color[GCOMP], color[BCOMP]);
01004 }
01005 
01006 /* Read a horizontal span of color pixels. */
01007 static void read_rgba_span_24(const GLcontext *ctx, 
01008                   struct gl_renderbuffer *rb,
01009                   GLuint n, GLint x, GLint y,
01010                   GLubyte rgba[][4] )
01011 {
01012     GLuint i;
01013     LPBYTE lpb;
01014     WMesaContext pwc = wmesa_context(ctx);
01015     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
01016     
01017     y = FLIP(y);
01018     lpb = ((LPBYTE)(pwfb->pbPixels + pwfb->ScanWidth * y)) + (3 * x);
01019     for (i=0; i<n; i++) {
01020     rgba[i][RCOMP] = lpb[3*i+2];
01021     rgba[i][GCOMP] = lpb[3*i+1];
01022     rgba[i][BCOMP] = lpb[3*i];
01023     rgba[i][ACOMP] = 255;
01024     }
01025 }
01026 
01027 
01028 /* Read an array of color pixels. */
01029 static void read_rgba_pixels_24(const GLcontext *ctx, 
01030                 struct gl_renderbuffer *rb,
01031                 GLuint n, const GLint x[], const GLint y[],
01032                 GLubyte rgba[][4])
01033 {
01034     GLuint i;
01035     LPBYTE lpb;
01036     WMesaContext pwc = wmesa_context(ctx);
01037     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
01038 
01039     for (i=0; i<n; i++) {
01040     GLint y2 = FLIP(y[i]);
01041     lpb = ((LPBYTE)(pwfb->pbPixels + pwfb->ScanWidth * y2)) + (3 * x[i]);
01042     rgba[i][RCOMP] = lpb[3*i+2];
01043     rgba[i][GCOMP] = lpb[3*i+1];
01044     rgba[i][BCOMP] = lpb[3*i];
01045     rgba[i][ACOMP] = 255;
01046   }
01047 }
01048 
01049 
01050 /*********************************************************************/
01051 
01052 /* DOUBLE BUFFER 16-bit */
01053 
01054 #define WMSETPIXEL16(pwc, y, x, r, g, b) { \
01055 LPWORD lpw = ((LPWORD)((pwc)->pbPixels + (pwc)->ScanWidth * (y)) + (x)); \
01056 *lpw = BGR16((r),(g),(b)); }
01057 
01058 
01059 
01060 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
01061 static void write_rgba_span_16(const GLcontext *ctx, 
01062                    struct gl_renderbuffer *rb, 
01063                    GLuint n, GLint x, GLint y,
01064                    const GLubyte rgba[][4], 
01065                    const GLubyte mask[] )
01066 {
01067     WMesaContext pwc = wmesa_context(ctx);
01068     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
01069     GLuint i;
01070     LPWORD lpw;
01071 
01072     (void) ctx;
01073     
01074     y=FLIP(y);
01075     lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x;
01076     if (mask) {
01077     for (i=0; i<n; i++)
01078         if (mask[i])
01079                 lpw[i] = BGR16(rgba[i][RCOMP], rgba[i][GCOMP], 
01080                    rgba[i][BCOMP]);
01081     }
01082     else {
01083     for (i=0; i<n; i++)
01084                 *lpw++ = BGR16(rgba[i][RCOMP], rgba[i][GCOMP], 
01085                    rgba[i][BCOMP]);
01086     }
01087 }
01088 
01089 
01090 /* Write a horizontal span of RGB color pixels with a boolean mask. */
01091 static void write_rgb_span_16(const GLcontext *ctx, 
01092                   struct gl_renderbuffer *rb, 
01093                   GLuint n, GLint x, GLint y,
01094                   const GLubyte rgb[][3], 
01095                   const GLubyte mask[] )
01096 {
01097     WMesaContext pwc = wmesa_context(ctx);
01098     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
01099     GLuint i;
01100     LPWORD lpw;
01101 
01102     (void) ctx;
01103     
01104     y=FLIP(y);
01105     lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x;
01106     if (mask) {
01107     for (i=0; i<n; i++)
01108         if (mask[i])
01109                 lpw[i] = BGR16(rgb[i][RCOMP], rgb[i][GCOMP], 
01110                    rgb[i][BCOMP]);
01111     }
01112     else {
01113     for (i=0; i<n; i++)
01114                 *lpw++ = BGR16(rgb[i][RCOMP], rgb[i][GCOMP], 
01115                    rgb[i][BCOMP]);
01116     }
01117 }
01118 
01119 /*
01120  * Write a horizontal span of pixels with a boolean mask.  The current color
01121  * is used for all pixels.
01122  */
01123 static void write_mono_rgba_span_16(const GLcontext *ctx, 
01124                     struct gl_renderbuffer *rb,
01125                     GLuint n, GLint x, GLint y,
01126                     const GLchan color[4], 
01127                     const GLubyte mask[])
01128 {
01129     LPWORD lpw;
01130     WORD pixel;
01131     GLuint i;
01132     WMesaContext pwc = wmesa_context(ctx);
01133     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
01134     (void) ctx;
01135     lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x;
01136     y=FLIP(y);
01137     pixel = BGR16(color[RCOMP], color[GCOMP], color[BCOMP]);
01138     if (mask) {
01139     for (i=0; i<n; i++)
01140         if (mask[i])
01141                 lpw[i] = pixel;
01142     }
01143     else
01144     for (i=0; i<n; i++)
01145                 *lpw++ = pixel;
01146 
01147 }
01148 
01149 /* Write an array of RGBA pixels with a boolean mask. */
01150 static void write_rgba_pixels_16(const GLcontext *ctx, 
01151                  struct gl_renderbuffer *rb,
01152                  GLuint n, const GLint x[], const GLint y[],
01153                  const GLubyte rgba[][4], 
01154                  const GLubyte mask[])
01155 {
01156     GLuint i;
01157     WMesaContext pwc = wmesa_context(ctx);
01158     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
01159     (void) ctx;
01160     for (i=0; i<n; i++)
01161     if (mask[i])
01162         WMSETPIXEL16(pwfb, FLIP(y[i]), x[i],
01163              rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
01164 }
01165 
01166 /*
01167  * Write an array of pixels with a boolean mask.  The current color
01168  * is used for all pixels.
01169  */
01170 static void write_mono_rgba_pixels_16(const GLcontext *ctx, 
01171                       struct gl_renderbuffer *rb,
01172                       GLuint n,
01173                       const GLint x[], const GLint y[],
01174                       const GLchan color[4],
01175                       const GLubyte mask[])
01176 {
01177     GLuint i;
01178     WMesaContext pwc = wmesa_context(ctx);
01179     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
01180     (void) ctx;
01181     for (i=0; i<n; i++)
01182     if (mask[i])
01183         WMSETPIXEL16(pwfb, FLIP(y[i]),x[i],color[RCOMP],
01184              color[GCOMP], color[BCOMP]);
01185 }
01186 
01187 /* Read a horizontal span of color pixels. */
01188 static void read_rgba_span_16(const GLcontext *ctx, 
01189                   struct gl_renderbuffer *rb,
01190                   GLuint n, GLint x, GLint y,
01191                   GLubyte rgba[][4] )
01192 {
01193     GLuint i, pixel;
01194     LPWORD lpw;
01195     WMesaContext pwc = wmesa_context(ctx);
01196     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
01197     
01198     y = FLIP(y);
01199     lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x;
01200     for (i=0; i<n; i++) {
01201     pixel = lpw[i];
01202     /* Windows uses 5,5,5 for 16-bit */
01203     rgba[i][RCOMP] = (pixel & 0x7c00) >> 7;
01204     rgba[i][GCOMP] = (pixel & 0x03e0) >> 2;
01205     rgba[i][BCOMP] = (pixel & 0x001f) << 3;
01206     rgba[i][ACOMP] = 255;
01207     }
01208 }
01209 
01210 
01211 /* Read an array of color pixels. */
01212 static void read_rgba_pixels_16(const GLcontext *ctx, 
01213                 struct gl_renderbuffer *rb,
01214                 GLuint n, const GLint x[], const GLint y[],
01215                 GLubyte rgba[][4])
01216 {
01217     GLuint i, pixel;
01218     LPWORD lpw;
01219     WMesaContext pwc = wmesa_context(ctx);
01220     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
01221 
01222     for (i=0; i<n; i++) {
01223     GLint y2 = FLIP(y[i]);
01224     lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y2)) + x[i];
01225     pixel = *lpw;
01226     /* Windows uses 5,5,5 for 16-bit */
01227     rgba[i][RCOMP] = (pixel & 0x7c00) >> 7;
01228     rgba[i][GCOMP] = (pixel & 0x03e0) >> 2;
01229     rgba[i][BCOMP] = (pixel & 0x001f) << 3;
01230     rgba[i][ACOMP] = 255;
01231   }
01232 }
01233 
01234 
01235 
01236 
01237 /**********************************************************************/
01238 /*****                   BUFFER Functions                         *****/
01239 /**********************************************************************/
01240 
01241 
01242 
01243 
01244 static void
01245 wmesa_delete_renderbuffer(struct gl_renderbuffer *rb)
01246 {
01247     _mesa_free(rb);
01248 }
01249 
01250 
01255 static GLboolean
01256 wmesa_renderbuffer_storage(GLcontext *ctx, 
01257                struct gl_renderbuffer *rb,
01258                GLenum internalFormat, 
01259                GLuint width, 
01260                GLuint height)
01261 {
01262     rb->Width = width;
01263     rb->Height = height;
01264     return GL_TRUE;
01265 }
01266 
01267 
01272 void wmesa_set_renderbuffer_funcs(struct gl_renderbuffer *rb, int pixelformat,
01273                                   BYTE cColorBits, int double_buffer)
01274 {
01275     if (double_buffer) {
01276         /* back buffer */
01277     /* Picking the correct span functions is important because
01278      * the DIB was allocated with the indicated depth. */
01279     switch(pixelformat) {
01280     case PF_5R6G5B:
01281         rb->PutRow = write_rgba_span_16;
01282         rb->PutRowRGB = write_rgb_span_16;
01283         rb->PutMonoRow = write_mono_rgba_span_16;
01284         rb->PutValues = write_rgba_pixels_16;
01285         rb->PutMonoValues = write_mono_rgba_pixels_16;
01286         rb->GetRow = read_rgba_span_16;
01287         rb->GetValues = read_rgba_pixels_16;
01288             rb->RedBits = 5;
01289             rb->GreenBits = 6;
01290             rb->BlueBits = 5;
01291         break;
01292     case PF_8R8G8B:
01293         if (cColorBits == 24)
01294         {
01295             rb->PutRow = write_rgba_span_24;
01296             rb->PutRowRGB = write_rgb_span_24;
01297             rb->PutMonoRow = write_mono_rgba_span_24;
01298             rb->PutValues = write_rgba_pixels_24;
01299             rb->PutMonoValues = write_mono_rgba_pixels_24;
01300             rb->GetRow = read_rgba_span_24;
01301             rb->GetValues = read_rgba_pixels_24;
01302             rb->RedBits = 8;
01303             rb->GreenBits = 8;
01304             rb->BlueBits = 8;       
01305         }
01306         else
01307         {
01308             rb->PutRow = write_rgba_span_32;
01309             rb->PutRowRGB = write_rgb_span_32;
01310             rb->PutMonoRow = write_mono_rgba_span_32;
01311             rb->PutValues = write_rgba_pixels_32;
01312             rb->PutMonoValues = write_mono_rgba_pixels_32;
01313             rb->GetRow = read_rgba_span_32;
01314             rb->GetValues = read_rgba_pixels_32;
01315             rb->RedBits = 8;
01316             rb->GreenBits = 8;
01317             rb->BlueBits = 8;
01318         }
01319         break;
01320     default:
01321         break;
01322     }
01323     }
01324     else {
01325         /* front buffer (actual Windows window) */
01326     rb->PutRow = write_rgba_span_front;
01327     rb->PutRowRGB = write_rgb_span_front;
01328     rb->PutMonoRow = write_mono_rgba_span_front;
01329     rb->PutValues = write_rgba_pixels_front;
01330     rb->PutMonoValues = write_mono_rgba_pixels_front;
01331     rb->GetRow = read_rgba_span_front;
01332     rb->GetValues = read_rgba_pixels_front;
01333         rb->RedBits = 8; /* XXX fix these (565?) */
01334         rb->GreenBits = 8;
01335         rb->BlueBits = 8;
01336     }
01337 }
01338 
01343 static void
01344 wmesa_resize_buffers(GLcontext *ctx, GLframebuffer *buffer,
01345                      GLuint width, GLuint height)
01346 {
01347     WMesaContext pwc = wmesa_context(ctx);
01348     WMesaFramebuffer pwfb = wmesa_framebuffer(buffer);
01349 
01350     if (pwfb->Base.Width != width || pwfb->Base.Height != height) {
01351     /* Realloc back buffer */
01352     if (ctx->Visual.doubleBufferMode == 1) {
01353         wmDeleteBackingStore(pwfb);
01354         wmCreateBackingStore(pwfb, width, height);
01355     }
01356     }
01357     _mesa_resize_framebuffer(ctx, buffer, width, height);
01358 }
01359 
01360 
01372 static void wmesa_viewport(GLcontext *ctx, 
01373                GLint x, GLint y, 
01374                GLsizei width, GLsizei height)
01375 {
01376     WMesaContext pwc = wmesa_context(ctx);
01377     GLuint new_width, new_height;
01378 
01379     wmesa_get_buffer_size(ctx->WinSysDrawBuffer, &new_width, &new_height);
01380 
01384     wmesa_resize_buffers(ctx, ctx->WinSysDrawBuffer, new_width, new_height);
01385     ctx->NewState |= _NEW_BUFFERS;  /* to update scissor / window bounds */
01386 }
01387 
01388 
01389 
01390 
01395 static void wmesa_update_state(GLcontext *ctx, GLuint new_state)
01396 {
01397     _swrast_InvalidateState(ctx, new_state);
01398     _swsetup_InvalidateState(ctx, new_state);
01399     _vbo_InvalidateState(ctx, new_state);
01400     _tnl_InvalidateState(ctx, new_state);
01401 
01402     /* TODO - This code is not complete yet because I 
01403      * don't know what to do for all state updates.
01404      */
01405 
01406     if (new_state & _NEW_BUFFERS) {
01407     }
01408 }
01409 
01410 
01411 
01412 
01413 
01414 /**********************************************************************/
01415 /*****                   WMESA Functions                          *****/
01416 /**********************************************************************/
01417 
01418 WMesaContext WMesaCreateContext(HDC hDC, 
01419                 HPALETTE* Pal,
01420                 GLboolean rgb_flag,
01421                 GLboolean db_flag,
01422                 GLboolean alpha_flag)
01423 {
01424     WMesaContext c;
01425     struct dd_function_table functions;
01426     GLint red_bits, green_bits, blue_bits, alpha_bits;
01427     GLcontext *ctx;
01428     GLvisual *visual;
01429 
01430     (void) Pal;
01431     
01432     /* Indexed mode not supported */
01433     if (!rgb_flag)
01434     return NULL;
01435 
01436     /* Allocate wmesa context */
01437     c = CALLOC_STRUCT(wmesa_context);
01438     if (!c)
01439     return NULL;
01440 
01441 #if 0
01442     /* I do not understand this contributed code */
01443     /* Support memory and device contexts */
01444     if(WindowFromDC(hDC) != NULL) {
01445     c->hDC = GetDC(WindowFromDC(hDC)); /* huh ???? */
01446     }
01447     else {
01448     c->hDC = hDC;
01449     }
01450 #else
01451     c->hDC = hDC;
01452 #endif
01453 
01454     /* Get data for visual */
01455     /* Dealing with this is actually a bit of overkill because Mesa will end
01456      * up treating all color component size requests less than 8 by using 
01457      * a single byte per channel.  In addition, the interface to the span
01458      * routines passes colors as an entire byte per channel anyway, so there
01459      * is nothing to be saved by telling the visual to be 16 bits if the device
01460      * is 16 bits.  That is, Mesa is going to compute colors down to 8 bits per
01461      * channel anyway.
01462      * But we go through the motions here anyway.
01463      */
01464     switch (GetDeviceCaps(c->hDC, BITSPIXEL)) {
01465     case 16:
01466     red_bits = green_bits = blue_bits = 5;
01467     alpha_bits = 0;
01468     break;
01469     default:
01470     red_bits = green_bits = blue_bits = 8;
01471     alpha_bits = 8;
01472     break;
01473     }
01474     /* Create visual based on flags */
01475     visual = _mesa_create_visual(rgb_flag,
01476                                  db_flag,    /* db_flag */
01477                                  GL_FALSE,   /* stereo */
01478                                  red_bits, green_bits, blue_bits, /* color RGB */
01479                                  alpha_flag ? alpha_bits : 0, /* color A */
01480                                  0,          /* index bits */
01481                                  DEFAULT_SOFTWARE_DEPTH_BITS, /* depth_bits */
01482                                  8,          /* stencil_bits */
01483                                  16,16,16,   /* accum RGB */
01484                                  alpha_flag ? 16 : 0, /* accum A */
01485                                  1);         /* num samples */
01486     
01487     if (!visual) {
01488     _mesa_free(c);
01489     return NULL;
01490     }
01491 
01492     /* Set up driver functions */
01493     _mesa_init_driver_functions(&functions);
01494     functions.GetString = wmesa_get_string;
01495     functions.UpdateState = wmesa_update_state;
01496     functions.GetBufferSize = wmesa_get_buffer_size;
01497     functions.Flush = wmesa_flush;
01498     functions.Clear = clear;
01499     functions.ClearIndex = clear_index;
01500     functions.ClearColor = clear_color;
01501     functions.ResizeBuffers = wmesa_resize_buffers;
01502     functions.Viewport = wmesa_viewport;
01503 
01504     /* initialize the Mesa context data */
01505     ctx = &c->gl_ctx;
01506     _mesa_initialize_context(ctx, visual, NULL, &functions, (void *)c);
01507 
01508     /* visual no longer needed - it was copied by _mesa_initialize_context() */
01509     _mesa_destroy_visual(visual);
01510 
01511     _mesa_enable_sw_extensions(ctx);
01512     _mesa_enable_1_3_extensions(ctx);
01513     _mesa_enable_1_4_extensions(ctx);
01514     _mesa_enable_1_5_extensions(ctx);
01515     _mesa_enable_2_0_extensions(ctx);
01516     _mesa_enable_2_1_extensions(ctx);
01517   
01518     /* Initialize the software rasterizer and helper modules. */
01519     if (!_swrast_CreateContext(ctx) ||
01520         !_vbo_CreateContext(ctx) ||
01521         !_tnl_CreateContext(ctx) ||
01522     !_swsetup_CreateContext(ctx)) {
01523     _mesa_free_context_data(ctx);
01524     _mesa_free(c);
01525     return NULL;
01526     }
01527     _swsetup_Wakeup(ctx);
01528     TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline;
01529 
01530     return c;
01531 }
01532 
01533 
01534 void WMesaDestroyContext( WMesaContext pwc )
01535 {
01536     GLcontext *ctx = &pwc->gl_ctx;
01537     WMesaFramebuffer pwfb;
01538     GET_CURRENT_CONTEXT(cur_ctx);
01539 
01540     if (cur_ctx == ctx) {
01541         /* unbind current if deleting current context */
01542         WMesaMakeCurrent(NULL, NULL);
01543     }
01544 
01545     /* clean up frame buffer resources */
01546     pwfb = wmesa_lookup_framebuffer(pwc->hDC);
01547     if (pwfb) {
01548     if (ctx->Visual.doubleBufferMode == 1)
01549         wmDeleteBackingStore(pwfb);
01550     wmesa_free_framebuffer(pwc->hDC);
01551     }
01552 
01553     /* Release for device, not memory contexts */
01554     if (WindowFromDC(pwc->hDC) != NULL)
01555     {
01556       ReleaseDC(WindowFromDC(pwc->hDC), pwc->hDC);
01557     }
01558     DeleteObject(pwc->clearPen); 
01559     DeleteObject(pwc->clearBrush); 
01560     
01561     _swsetup_DestroyContext(ctx);
01562     _tnl_DestroyContext(ctx);
01563     _vbo_DestroyContext(ctx);
01564     _swrast_DestroyContext(ctx);
01565     
01566     _mesa_free_context_data(ctx);
01567     _mesa_free(pwc);
01568 }
01569 
01570 
01574 struct gl_renderbuffer *
01575 wmesa_new_renderbuffer(void)
01576 {
01577     struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer);
01578     if (!rb)
01579         return NULL;
01580 
01581     _mesa_init_renderbuffer(rb, (GLuint)0);
01582     
01583     rb->_BaseFormat = GL_RGBA;
01584     rb->InternalFormat = GL_RGBA;
01585     rb->DataType = CHAN_TYPE;
01586     rb->Delete = wmesa_delete_renderbuffer;
01587     rb->AllocStorage = wmesa_renderbuffer_storage;
01588     return rb;
01589 }
01590 
01591 
01592 void WMesaMakeCurrent(WMesaContext c, HDC hdc)
01593 {
01594     WMesaFramebuffer pwfb;
01595 
01596     {
01597         /* return if already current */
01598         GET_CURRENT_CONTEXT(ctx);
01599         WMesaContext pwc = wmesa_context(ctx);
01600         if (pwc && c == pwc && pwc->hDC == hdc)
01601             return;
01602     }
01603 
01604     pwfb = wmesa_lookup_framebuffer(hdc);
01605 
01606     /* Lazy creation of framebuffers */
01607     if (c && !pwfb && hdc) {
01608         struct gl_renderbuffer *rb;
01609         GLvisual *visual = &c->gl_ctx.Visual;
01610         GLuint width, height;
01611 
01612         get_window_size(hdc, &width, &height);
01613 
01614     c->clearPen = CreatePen(PS_SOLID, 1, 0); 
01615     c->clearBrush = CreateSolidBrush(0); 
01616 
01617         pwfb = wmesa_new_framebuffer(hdc, visual);
01618 
01619     /* Create back buffer if double buffered */
01620     if (visual->doubleBufferMode == 1) {
01621         wmCreateBackingStore(pwfb, width, height);
01622     }
01623     
01624         /* make render buffers */
01625         if (visual->doubleBufferMode == 1) {
01626             rb = wmesa_new_renderbuffer();
01627             _mesa_add_renderbuffer(&pwfb->Base, BUFFER_BACK_LEFT, rb);
01628             wmesa_set_renderbuffer_funcs(rb, pwfb->pixelformat, pwfb->cColorBits, 1);
01629     }
01630         rb = wmesa_new_renderbuffer();
01631         _mesa_add_renderbuffer(&pwfb->Base, BUFFER_FRONT_LEFT, rb);
01632         wmesa_set_renderbuffer_funcs(rb, pwfb->pixelformat, pwfb->cColorBits, 0);
01633 
01634     /* Let Mesa own the Depth, Stencil, and Accum buffers */
01635         _mesa_add_soft_renderbuffers(&pwfb->Base,
01636                                      GL_FALSE, /* color */
01637                                      visual->depthBits > 0,
01638                                      visual->stencilBits > 0,
01639                                      visual->accumRedBits > 0,
01640                                      visual->alphaBits >0, 
01641                                      GL_FALSE);
01642     }
01643 
01644     if (c && pwfb)
01645     _mesa_make_current(&c->gl_ctx, &pwfb->Base, &pwfb->Base);
01646     else
01647         _mesa_make_current(NULL, NULL, NULL);
01648 }
01649 
01650 
01651 void WMesaSwapBuffers( HDC hdc )
01652 {
01653     GET_CURRENT_CONTEXT(ctx);
01654     WMesaContext pwc = wmesa_context(ctx);
01655     WMesaFramebuffer pwfb = wmesa_lookup_framebuffer(hdc);
01656 
01657     if (!pwfb) {
01658         _mesa_problem(NULL, "wmesa: swapbuffers on unknown hdc");
01659         return;
01660     }
01661 
01662     /* If we're swapping the buffer associated with the current context
01663      * we have to flush any pending rendering commands first.
01664      */
01665     if (pwc->hDC == hdc) {
01666     _mesa_notifySwapBuffers(ctx);
01667 
01668     BitBlt(pwfb->hDC, 0, 0, pwfb->Base.Width, pwfb->Base.Height,
01669            pwfb->dib_hDC, 0, 0, SRCCOPY);
01670     }
01671     else {
01672         /* XXX for now only allow swapping current window */
01673         _mesa_problem(NULL, "wmesa: can't swap non-current window");
01674     }
01675 }
01676 
01677 void WMesaShareLists(WMesaContext ctx_to_share, WMesaContext ctx)
01678 {
01679     _mesa_share_state(&ctx->gl_ctx, &ctx_to_share->gl_ctx); 
01680 }

Generated on Sun May 27 2012 04:19:57 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.