Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenwmesa.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
1.7.6.1
|