wmesa.c revision 76fb8089103e9dba9aaa7232c86d864d5874a08f
1/* 2 * Windows (Win32/Win64) device driver for Mesa 3 * 4 */ 5 6#include "wmesadef.h" 7#include "colors.h" 8#include <GL/wmesa.h> 9#include <winuser.h> 10#include "context.h" 11#include "extensions.h" 12#include "framebuffer.h" 13#include "renderbuffer.h" 14#include "drivers/common/driverfuncs.h" 15#include "vbo/vbo.h" 16#include "swrast/swrast.h" 17#include "swrast_setup/swrast_setup.h" 18#include "tnl/tnl.h" 19#include "tnl/t_context.h" 20#include "tnl/t_pipeline.h" 21 22 23/* linked list of our Framebuffers (windows) */ 24static WMesaFramebuffer FirstFramebuffer = NULL; 25 26 27/** 28 * Create a new WMesaFramebuffer object which will correspond to the 29 * given HDC (Window handle). 30 */ 31WMesaFramebuffer 32wmesa_new_framebuffer(HDC hdc, GLvisual *visual) 33{ 34 WMesaFramebuffer pwfb 35 = (WMesaFramebuffer) malloc(sizeof(struct wmesa_framebuffer)); 36 if (pwfb) { 37 _mesa_initialize_framebuffer(&pwfb->Base, visual); 38 pwfb->hDC = hdc; 39 /* insert at head of list */ 40 pwfb->next = FirstFramebuffer; 41 FirstFramebuffer = pwfb; 42 } 43 return pwfb; 44} 45 46/** 47 * Given an hdc, free the corresponding WMesaFramebuffer 48 */ 49void 50wmesa_free_framebuffer(HDC hdc) 51{ 52 WMesaFramebuffer pwfb, prev; 53 for (pwfb = FirstFramebuffer; pwfb; pwfb = pwfb->next) { 54 if (pwfb->hDC == hdc) 55 break; 56 prev = pwfb; 57 } 58 if (pwfb) { 59 if (pwfb == FirstFramebuffer) 60 FirstFramebuffer = pwfb->next; 61 else 62 prev->next = pwfb->next; 63 free(pwfb); 64 } 65} 66 67/** 68 * Given an hdc, return the corresponding WMesaFramebuffer 69 */ 70WMesaFramebuffer 71wmesa_lookup_framebuffer(HDC hdc) 72{ 73 WMesaFramebuffer pwfb; 74 for (pwfb = FirstFramebuffer; pwfb; pwfb = pwfb->next) { 75 if (pwfb->hDC == hdc) 76 return pwfb; 77 } 78 return NULL; 79} 80 81 82/** 83 * Given a GLframebuffer, return the corresponding WMesaFramebuffer. 84 */ 85static WMesaFramebuffer wmesa_framebuffer(GLframebuffer *fb) 86{ 87 return (WMesaFramebuffer) fb; 88} 89 90 91/** 92 * Given a GLcontext, return the corresponding WMesaContext. 93 */ 94static WMesaContext wmesa_context(const GLcontext *ctx) 95{ 96 return (WMesaContext) ctx; 97} 98 99 100/* 101 * Every driver should implement a GetString function in order to 102 * return a meaningful GL_RENDERER string. 103 */ 104static const GLubyte *wmesa_get_string(GLcontext *ctx, GLenum name) 105{ 106 return (name == GL_RENDERER) ? 107 (GLubyte *) "Mesa Windows GDI Driver" : NULL; 108} 109 110 111/* 112 * Determine the pixel format based on the pixel size. 113 */ 114static void wmSetPixelFormat(WMesaFramebuffer pwfb, HDC hDC) 115{ 116 pwfb->cColorBits = GetDeviceCaps(hDC, BITSPIXEL); 117 118 /* Only 16 and 32 bit targets are supported now */ 119 assert(pwfb->cColorBits == 0 || 120 pwfb->cColorBits == 16 || 121 pwfb->cColorBits == 32); 122 123 switch(pwfb->cColorBits){ 124 case 8: 125 pwfb->pixelformat = PF_INDEX8; 126 break; 127 case 16: 128 pwfb->pixelformat = PF_5R6G5B; 129 break; 130 case 32: 131 pwfb->pixelformat = PF_8R8G8B; 132 break; 133 default: 134 pwfb->pixelformat = PF_BADFORMAT; 135 } 136} 137 138 139/** 140 * Create DIB for back buffer. 141 * We write into this memory with the span routines and then blit it 142 * to the window on a buffer swap. 143 */ 144BOOL wmCreateBackingStore(WMesaFramebuffer pwfb, long lxSize, long lySize) 145{ 146 HDC hdc = pwfb->hDC; 147 LPBITMAPINFO pbmi = &(pwfb->bmi); 148 HDC hic; 149 150 pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 151 pbmi->bmiHeader.biWidth = lxSize; 152 pbmi->bmiHeader.biHeight= -lySize; 153 pbmi->bmiHeader.biPlanes = 1; 154 pbmi->bmiHeader.biBitCount = GetDeviceCaps(pwfb->hDC, BITSPIXEL); 155 pbmi->bmiHeader.biCompression = BI_RGB; 156 pbmi->bmiHeader.biSizeImage = 0; 157 pbmi->bmiHeader.biXPelsPerMeter = 0; 158 pbmi->bmiHeader.biYPelsPerMeter = 0; 159 pbmi->bmiHeader.biClrUsed = 0; 160 pbmi->bmiHeader.biClrImportant = 0; 161 162 pwfb->cColorBits = pbmi->bmiHeader.biBitCount; 163 pwfb->ScanWidth = (lxSize * (pwfb->cColorBits / 8) + 3) & ~3; 164 165 hic = CreateIC("display", NULL, NULL, NULL); 166 pwfb->dib_hDC = CreateCompatibleDC(hic); 167 168 pwfb->hbmDIB = CreateDIBSection(hic, 169 &pwfb->bmi, 170 DIB_RGB_COLORS, 171 (void **)&(pwfb->pbPixels), 172 0, 173 0); 174 pwfb->hOldBitmap = SelectObject(pwfb->dib_hDC, pwfb->hbmDIB); 175 176 DeleteDC(hic); 177 178 wmSetPixelFormat(pwfb, pwfb->hDC); 179 return TRUE; 180} 181 182 183static wmDeleteBackingStore(WMesaFramebuffer pwfb) 184{ 185 if (pwfb->hbmDIB) { 186 SelectObject(pwfb->dib_hDC, pwfb->hOldBitmap); 187 DeleteDC(pwfb->dib_hDC); 188 DeleteObject(pwfb->hbmDIB); 189 } 190} 191 192 193/** 194 * Find the width and height of the window named by hdc. 195 */ 196static void 197get_window_size(HDC hdc, GLuint *width, GLuint *height) 198{ 199 if (WindowFromDC(hdc)) { 200 RECT rect; 201 GetClientRect(WindowFromDC(hdc), &rect); 202 *width = rect.right - rect.left; 203 *height = rect.bottom - rect.top; 204 } 205 else { /* Memory context */ 206 /* From contributed code - use the size of the desktop 207 * for the size of a memory context (?) */ 208 *width = GetDeviceCaps(hdc, HORZRES); 209 *height = GetDeviceCaps(hdc, VERTRES); 210 } 211} 212 213 214static void 215wmesa_get_buffer_size(GLframebuffer *buffer, GLuint *width, GLuint *height) 216{ 217 WMesaFramebuffer pwfb = wmesa_framebuffer(buffer); 218 get_window_size(pwfb->hDC, width, height); 219} 220 221 222static void wmesa_flush(GLcontext *ctx) 223{ 224 WMesaContext pwc = wmesa_context(ctx); 225 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->WinSysDrawBuffer); 226 227 if (ctx->Visual.doubleBufferMode == 1) { 228 BitBlt(pwfb->hDC, 0, 0, pwfb->Base.Width, pwfb->Base.Height, 229 pwfb->dib_hDC, 0, 0, SRCCOPY); 230 } 231 else { 232 /* Do nothing for single buffer */ 233 } 234} 235 236 237/**********************************************************************/ 238/***** CLEAR Functions *****/ 239/**********************************************************************/ 240 241/* If we do not implement these, Mesa clears the buffers via the pixel 242 * span writing interface, which is very slow for a clear operation. 243 */ 244 245/* 246 * Set the color index used to clear the color buffer. 247 */ 248static void clear_index(GLcontext *ctx, GLuint index) 249{ 250 WMesaContext pwc = wmesa_context(ctx); 251 /* Note that indexed mode is not supported yet */ 252 pwc->clearColorRef = RGB(0,0,0); 253} 254 255/* 256 * Set the color used to clear the color buffer. 257 */ 258static void clear_color(GLcontext *ctx, const GLfloat color[4]) 259{ 260 WMesaContext pwc = wmesa_context(ctx); 261 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 262 GLubyte col[3]; 263 UINT bytesPerPixel = pwfb->cColorBits / 8; 264 265 CLAMPED_FLOAT_TO_UBYTE(col[0], color[0]); 266 CLAMPED_FLOAT_TO_UBYTE(col[1], color[1]); 267 CLAMPED_FLOAT_TO_UBYTE(col[2], color[2]); 268 pwc->clearColorRef = RGB(col[0], col[1], col[2]); 269 DeleteObject(pwc->clearPen); 270 DeleteObject(pwc->clearBrush); 271 pwc->clearPen = CreatePen(PS_SOLID, 1, pwc->clearColorRef); 272 pwc->clearBrush = CreateSolidBrush(pwc->clearColorRef); 273} 274 275 276/* 277 * Clear the specified region of the color buffer using the clear color 278 * or index as specified by one of the two functions above. 279 * 280 * This procedure clears either the front and/or the back COLOR buffers. 281 * Only the "left" buffer is cleared since we are not stereo. 282 * Clearing of the other non-color buffers is left to the swrast. 283 */ 284 285static void clear(GLcontext *ctx, GLbitfield mask) 286{ 287#define FLIP(Y) (ctx->DrawBuffer->Height - (Y) - 1) 288 const GLint x = ctx->DrawBuffer->_Xmin; 289 const GLint y = ctx->DrawBuffer->_Ymin; 290 const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; 291 const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; 292 293 WMesaContext pwc = wmesa_context(ctx); 294 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 295 int done = 0; 296 297 /* Let swrast do all the work if the masks are not set to 298 * clear all channels. */ 299 if (ctx->Color.ColorMask[0] != 0xff || 300 ctx->Color.ColorMask[1] != 0xff || 301 ctx->Color.ColorMask[2] != 0xff || 302 ctx->Color.ColorMask[3] != 0xff) { 303 _swrast_Clear(ctx, mask); 304 return; 305 } 306 307 /* Back buffer */ 308 if (mask & BUFFER_BIT_BACK_LEFT) { 309 310 int i, rowSize; 311 UINT bytesPerPixel = pwfb->cColorBits / 8; 312 LPBYTE lpb, clearRow; 313 LPWORD lpw; 314 BYTE bColor; 315 WORD wColor; 316 BYTE r, g, b; 317 DWORD dwColor; 318 LPDWORD lpdw; 319 320 /* Try for a fast clear - clearing entire buffer with a single 321 * byte value. */ 322 if (width == ctx->DrawBuffer->Width && 323 height == ctx->DrawBuffer->Height) { /* entire buffer */ 324 /* Now check for an easy clear value */ 325 switch (bytesPerPixel) { 326 case 1: 327 bColor = BGR8(GetRValue(pwc->clearColorRef), 328 GetGValue(pwc->clearColorRef), 329 GetBValue(pwc->clearColorRef)); 330 memset(pwfb->pbPixels, bColor, 331 pwfb->ScanWidth * height); 332 done = 1; 333 break; 334 case 2: 335 wColor = BGR16(GetRValue(pwc->clearColorRef), 336 GetGValue(pwc->clearColorRef), 337 GetBValue(pwc->clearColorRef)); 338 if (((wColor >> 8) & 0xff) == (wColor & 0xff)) { 339 memset(pwfb->pbPixels, wColor & 0xff, 340 pwfb->ScanWidth * height); 341 done = 1; 342 } 343 break; 344 case 3: 345 /* fall through */ 346 case 4: 347 if (GetRValue(pwc->clearColorRef) == 348 GetGValue(pwc->clearColorRef) && 349 GetRValue(pwc->clearColorRef) == 350 GetBValue(pwc->clearColorRef)) { 351 memset(pwfb->pbPixels, 352 GetRValue(pwc->clearColorRef), 353 pwfb->ScanWidth * height); 354 done = 1; 355 } 356 break; 357 default: 358 break; 359 } 360 } /* all */ 361 362 if (!done) { 363 /* Need to clear a row at a time. Begin by setting the first 364 * row in the area to be cleared to the clear color. */ 365 366 clearRow = pwfb->pbPixels + 367 pwfb->ScanWidth * FLIP(y) + 368 bytesPerPixel * x; 369 switch (bytesPerPixel) { 370 case 1: 371 lpb = clearRow; 372 bColor = BGR8(GetRValue(pwc->clearColorRef), 373 GetGValue(pwc->clearColorRef), 374 GetBValue(pwc->clearColorRef)); 375 memset(lpb, bColor, width); 376 break; 377 case 2: 378 lpw = (LPWORD)clearRow; 379 wColor = BGR16(GetRValue(pwc->clearColorRef), 380 GetGValue(pwc->clearColorRef), 381 GetBValue(pwc->clearColorRef)); 382 for (i=0; i<width; i++) 383 *lpw++ = wColor; 384 break; 385 case 3: 386 lpb = clearRow; 387 r = GetRValue(pwc->clearColorRef); 388 g = GetGValue(pwc->clearColorRef); 389 b = GetBValue(pwc->clearColorRef); 390 for (i=0; i<width; i++) { 391 *lpb++ = b; 392 *lpb++ = g; 393 *lpb++ = r; 394 } 395 break; 396 case 4: 397 lpdw = (LPDWORD)clearRow; 398 dwColor = BGR32(GetRValue(pwc->clearColorRef), 399 GetGValue(pwc->clearColorRef), 400 GetBValue(pwc->clearColorRef)); 401 for (i=0; i<width; i++) 402 *lpdw++ = dwColor; 403 break; 404 default: 405 break; 406 } /* switch */ 407 408 /* copy cleared row to other rows in buffer */ 409 lpb = clearRow - pwfb->ScanWidth; 410 rowSize = width * bytesPerPixel; 411 for (i=1; i<height; i++) { 412 memcpy(lpb, clearRow, rowSize); 413 lpb -= pwfb->ScanWidth; 414 } 415 } /* not done */ 416 mask &= ~BUFFER_BIT_BACK_LEFT; 417 } /* back buffer */ 418 419 /* front buffer */ 420 if (mask & BUFFER_BIT_FRONT_LEFT) { 421 HDC DC = pwc->hDC; 422 HPEN Old_Pen = SelectObject(DC, pwc->clearPen); 423 HBRUSH Old_Brush = SelectObject(DC, pwc->clearBrush); 424 Rectangle(DC, 425 x, 426 FLIP(y) + 1, 427 x + width + 1, 428 FLIP(y) - height + 1); 429 SelectObject(DC, Old_Pen); 430 SelectObject(DC, Old_Brush); 431 mask &= ~BUFFER_BIT_FRONT_LEFT; 432 } /* front buffer */ 433 434 /* Call swrast if there is anything left to clear (like DEPTH) */ 435 if (mask) 436 _swrast_Clear(ctx, mask); 437 438#undef FLIP 439} 440 441 442/**********************************************************************/ 443/***** PIXEL Functions *****/ 444/**********************************************************************/ 445 446#define FLIP(Y) (rb->Height - (Y) - 1) 447 448 449/** 450 ** Front Buffer reading/writing 451 ** These are slow, but work with all non-indexed visual types. 452 **/ 453 454/* Write a horizontal span of RGBA color pixels with a boolean mask. */ 455static void write_rgba_span_front(const GLcontext *ctx, 456 struct gl_renderbuffer *rb, 457 GLuint n, GLint x, GLint y, 458 const GLubyte rgba[][4], 459 const GLubyte mask[] ) 460{ 461 WMesaContext pwc = wmesa_context(ctx); 462 GLuint i; 463 464 (void) ctx; 465 y=FLIP(y); 466 if (mask) { 467 for (i=0; i<n; i++) 468 if (mask[i]) 469 SetPixel(pwc->hDC, x+i, y, RGB(rgba[i][RCOMP], rgba[i][GCOMP], 470 rgba[i][BCOMP])); 471 } 472 else { 473 for (i=0; i<n; i++) 474 SetPixel(pwc->hDC, x+i, y, RGB(rgba[i][RCOMP], rgba[i][GCOMP], 475 rgba[i][BCOMP])); 476 } 477 478} 479 480/* Write a horizontal span of RGB color pixels with a boolean mask. */ 481static void write_rgb_span_front(const GLcontext *ctx, 482 struct gl_renderbuffer *rb, 483 GLuint n, GLint x, GLint y, 484 const GLubyte rgb[][3], 485 const GLubyte mask[] ) 486{ 487 WMesaContext pwc = wmesa_context(ctx); 488 GLuint i; 489 490 (void) ctx; 491 y=FLIP(y); 492 if (mask) { 493 for (i=0; i<n; i++) 494 if (mask[i]) 495 SetPixel(pwc->hDC, x+i, y, RGB(rgb[i][RCOMP], rgb[i][GCOMP], 496 rgb[i][BCOMP])); 497 } 498 else { 499 for (i=0; i<n; i++) 500 SetPixel(pwc->hDC, x+i, y, RGB(rgb[i][RCOMP], rgb[i][GCOMP], 501 rgb[i][BCOMP])); 502 } 503 504} 505 506/* 507 * Write a horizontal span of pixels with a boolean mask. The current color 508 * is used for all pixels. 509 */ 510static void write_mono_rgba_span_front(const GLcontext *ctx, 511 struct gl_renderbuffer *rb, 512 GLuint n, GLint x, GLint y, 513 const GLchan color[4], 514 const GLubyte mask[]) 515{ 516 GLuint i; 517 WMesaContext pwc = wmesa_context(ctx); 518 COLORREF colorref; 519 520 (void) ctx; 521 colorref = RGB(color[RCOMP], color[GCOMP], color[BCOMP]); 522 y=FLIP(y); 523 if (mask) { 524 for (i=0; i<n; i++) 525 if (mask[i]) 526 SetPixel(pwc->hDC, x+i, y, colorref); 527 } 528 else 529 for (i=0; i<n; i++) 530 SetPixel(pwc->hDC, x+i, y, colorref); 531 532} 533 534/* Write an array of RGBA pixels with a boolean mask. */ 535static void write_rgba_pixels_front(const GLcontext *ctx, 536 struct gl_renderbuffer *rb, 537 GLuint n, 538 const GLint x[], const GLint y[], 539 const GLubyte rgba[][4], 540 const GLubyte mask[] ) 541{ 542 GLuint i; 543 WMesaContext pwc = wmesa_context(ctx); 544 (void) ctx; 545 for (i=0; i<n; i++) 546 if (mask[i]) 547 SetPixel(pwc->hDC, x[i], FLIP(y[i]), 548 RGB(rgba[i][RCOMP], rgba[i][GCOMP], 549 rgba[i][BCOMP])); 550} 551 552 553 554/* 555 * Write an array of pixels with a boolean mask. The current color 556 * is used for all pixels. 557 */ 558static void write_mono_rgba_pixels_front(const GLcontext *ctx, 559 struct gl_renderbuffer *rb, 560 GLuint n, 561 const GLint x[], const GLint y[], 562 const GLchan color[4], 563 const GLubyte mask[] ) 564{ 565 GLuint i; 566 WMesaContext pwc = wmesa_context(ctx); 567 COLORREF colorref; 568 (void) ctx; 569 colorref = RGB(color[RCOMP], color[GCOMP], color[BCOMP]); 570 for (i=0; i<n; i++) 571 if (mask[i]) 572 SetPixel(pwc->hDC, x[i], FLIP(y[i]), colorref); 573} 574 575/* Read a horizontal span of color pixels. */ 576static void read_rgba_span_front(const GLcontext *ctx, 577 struct gl_renderbuffer *rb, 578 GLuint n, GLint x, GLint y, 579 GLubyte rgba[][4] ) 580{ 581 WMesaContext pwc = wmesa_context(ctx); 582 GLuint i; 583 COLORREF Color; 584 y = FLIP(y); 585 for (i=0; i<n; i++) { 586 Color = GetPixel(pwc->hDC, x+i, y); 587 rgba[i][RCOMP] = GetRValue(Color); 588 rgba[i][GCOMP] = GetGValue(Color); 589 rgba[i][BCOMP] = GetBValue(Color); 590 rgba[i][ACOMP] = 255; 591 } 592} 593 594 595/* Read an array of color pixels. */ 596static void read_rgba_pixels_front(const GLcontext *ctx, 597 struct gl_renderbuffer *rb, 598 GLuint n, const GLint x[], const GLint y[], 599 GLubyte rgba[][4]) 600{ 601 WMesaContext pwc = wmesa_context(ctx); 602 GLuint i; 603 COLORREF Color; 604 for (i=0; i<n; i++) { 605 GLint y2 = FLIP(y[i]); 606 Color = GetPixel(pwc->hDC, x[i], y2); 607 rgba[i][RCOMP] = GetRValue(Color); 608 rgba[i][GCOMP] = GetGValue(Color); 609 rgba[i][BCOMP] = GetBValue(Color); 610 rgba[i][ACOMP] = 255; 611 } 612} 613 614/*********************************************************************/ 615 616/* DOUBLE BUFFER 32-bit */ 617 618#define WMSETPIXEL32(pwc, y, x, r, g, b) { \ 619LPDWORD lpdw = ((LPDWORD)((pwc)->pbPixels + (pwc)->ScanWidth * (y)) + (x)); \ 620*lpdw = BGR32((r),(g),(b)); } 621 622 623 624/* Write a horizontal span of RGBA color pixels with a boolean mask. */ 625static void write_rgba_span_32(const GLcontext *ctx, 626 struct gl_renderbuffer *rb, 627 GLuint n, GLint x, GLint y, 628 const GLubyte rgba[][4], 629 const GLubyte mask[] ) 630{ 631 WMesaContext pwc = wmesa_context(ctx); 632 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 633 GLuint i; 634 LPDWORD lpdw; 635 636 (void) ctx; 637 638 y=FLIP(y); 639 lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x; 640 if (mask) { 641 for (i=0; i<n; i++) 642 if (mask[i]) 643 lpdw[i] = BGR32(rgba[i][RCOMP], rgba[i][GCOMP], 644 rgba[i][BCOMP]); 645 } 646 else { 647 for (i=0; i<n; i++) 648 *lpdw++ = BGR32(rgba[i][RCOMP], rgba[i][GCOMP], 649 rgba[i][BCOMP]); 650 } 651} 652 653 654/* Write a horizontal span of RGB color pixels with a boolean mask. */ 655static void write_rgb_span_32(const GLcontext *ctx, 656 struct gl_renderbuffer *rb, 657 GLuint n, GLint x, GLint y, 658 const GLubyte rgb[][3], 659 const GLubyte mask[] ) 660{ 661 WMesaContext pwc = wmesa_context(ctx); 662 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 663 GLuint i; 664 LPDWORD lpdw; 665 666 (void) ctx; 667 668 y=FLIP(y); 669 lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x; 670 if (mask) { 671 for (i=0; i<n; i++) 672 if (mask[i]) 673 lpdw[i] = BGR32(rgb[i][RCOMP], rgb[i][GCOMP], 674 rgb[i][BCOMP]); 675 } 676 else { 677 for (i=0; i<n; i++) 678 *lpdw++ = BGR32(rgb[i][RCOMP], rgb[i][GCOMP], 679 rgb[i][BCOMP]); 680 } 681} 682 683/* 684 * Write a horizontal span of pixels with a boolean mask. The current color 685 * is used for all pixels. 686 */ 687static void write_mono_rgba_span_32(const GLcontext *ctx, 688 struct gl_renderbuffer *rb, 689 GLuint n, GLint x, GLint y, 690 const GLchan color[4], 691 const GLubyte mask[]) 692{ 693 LPDWORD lpdw; 694 DWORD pixel; 695 GLuint i; 696 WMesaContext pwc = wmesa_context(ctx); 697 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 698 lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x; 699 y=FLIP(y); 700 pixel = BGR32(color[RCOMP], color[GCOMP], color[BCOMP]); 701 if (mask) { 702 for (i=0; i<n; i++) 703 if (mask[i]) 704 lpdw[i] = pixel; 705 } 706 else 707 for (i=0; i<n; i++) 708 *lpdw++ = pixel; 709 710} 711 712/* Write an array of RGBA pixels with a boolean mask. */ 713static void write_rgba_pixels_32(const GLcontext *ctx, 714 struct gl_renderbuffer *rb, 715 GLuint n, const GLint x[], const GLint y[], 716 const GLubyte rgba[][4], 717 const GLubyte mask[]) 718{ 719 GLuint i; 720 WMesaContext pwc = wmesa_context(ctx); 721 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 722 for (i=0; i<n; i++) 723 if (mask[i]) 724 WMSETPIXEL32(pwfb, FLIP(y[i]), x[i], 725 rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); 726} 727 728/* 729 * Write an array of pixels with a boolean mask. The current color 730 * is used for all pixels. 731 */ 732static void write_mono_rgba_pixels_32(const GLcontext *ctx, 733 struct gl_renderbuffer *rb, 734 GLuint n, 735 const GLint x[], const GLint y[], 736 const GLchan color[4], 737 const GLubyte mask[]) 738{ 739 GLuint i; 740 WMesaContext pwc = wmesa_context(ctx); 741 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 742 for (i=0; i<n; i++) 743 if (mask[i]) 744 WMSETPIXEL32(pwfb, FLIP(y[i]),x[i],color[RCOMP], 745 color[GCOMP], color[BCOMP]); 746} 747 748/* Read a horizontal span of color pixels. */ 749static void read_rgba_span_32(const GLcontext *ctx, 750 struct gl_renderbuffer *rb, 751 GLuint n, GLint x, GLint y, 752 GLubyte rgba[][4] ) 753{ 754 GLuint i; 755 DWORD pixel; 756 LPDWORD lpdw; 757 WMesaContext pwc = wmesa_context(ctx); 758 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 759 760 y = FLIP(y); 761 lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x; 762 for (i=0; i<n; i++) { 763 pixel = lpdw[i]; 764 rgba[i][RCOMP] = (pixel & 0x00ff0000) >> 16; 765 rgba[i][GCOMP] = (pixel & 0x0000ff00) >> 8; 766 rgba[i][BCOMP] = (pixel & 0x000000ff); 767 rgba[i][ACOMP] = 255; 768 } 769} 770 771 772/* Read an array of color pixels. */ 773static void read_rgba_pixels_32(const GLcontext *ctx, 774 struct gl_renderbuffer *rb, 775 GLuint n, const GLint x[], const GLint y[], 776 GLubyte rgba[][4]) 777{ 778 GLuint i; 779 DWORD pixel; 780 LPDWORD lpdw; 781 WMesaContext pwc = wmesa_context(ctx); 782 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 783 784 for (i=0; i<n; i++) { 785 GLint y2 = FLIP(y[i]); 786 lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y2)) + x[i]; 787 pixel = *lpdw; 788 rgba[i][RCOMP] = (pixel & 0x00ff0000) >> 16; 789 rgba[i][GCOMP] = (pixel & 0x0000ff00) >> 8; 790 rgba[i][BCOMP] = (pixel & 0x000000ff); 791 rgba[i][ACOMP] = 255; 792 } 793} 794 795 796/*********************************************************************/ 797 798/* DOUBLE BUFFER 16-bit */ 799 800#define WMSETPIXEL16(pwc, y, x, r, g, b) { \ 801LPWORD lpw = ((LPWORD)((pwc)->pbPixels + (pwc)->ScanWidth * (y)) + (x)); \ 802*lpw = BGR16((r),(g),(b)); } 803 804 805 806/* Write a horizontal span of RGBA color pixels with a boolean mask. */ 807static void write_rgba_span_16(const GLcontext *ctx, 808 struct gl_renderbuffer *rb, 809 GLuint n, GLint x, GLint y, 810 const GLubyte rgba[][4], 811 const GLubyte mask[] ) 812{ 813 WMesaContext pwc = wmesa_context(ctx); 814 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 815 GLuint i; 816 LPWORD lpw; 817 818 (void) ctx; 819 820 y=FLIP(y); 821 lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x; 822 if (mask) { 823 for (i=0; i<n; i++) 824 if (mask[i]) 825 lpw[i] = BGR16(rgba[i][RCOMP], rgba[i][GCOMP], 826 rgba[i][BCOMP]); 827 } 828 else { 829 for (i=0; i<n; i++) 830 *lpw++ = BGR16(rgba[i][RCOMP], rgba[i][GCOMP], 831 rgba[i][BCOMP]); 832 } 833} 834 835 836/* Write a horizontal span of RGB color pixels with a boolean mask. */ 837static void write_rgb_span_16(const GLcontext *ctx, 838 struct gl_renderbuffer *rb, 839 GLuint n, GLint x, GLint y, 840 const GLubyte rgb[][3], 841 const GLubyte mask[] ) 842{ 843 WMesaContext pwc = wmesa_context(ctx); 844 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 845 GLuint i; 846 LPWORD lpw; 847 848 (void) ctx; 849 850 y=FLIP(y); 851 lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x; 852 if (mask) { 853 for (i=0; i<n; i++) 854 if (mask[i]) 855 lpw[i] = BGR16(rgb[i][RCOMP], rgb[i][GCOMP], 856 rgb[i][BCOMP]); 857 } 858 else { 859 for (i=0; i<n; i++) 860 *lpw++ = BGR16(rgb[i][RCOMP], rgb[i][GCOMP], 861 rgb[i][BCOMP]); 862 } 863} 864 865/* 866 * Write a horizontal span of pixels with a boolean mask. The current color 867 * is used for all pixels. 868 */ 869static void write_mono_rgba_span_16(const GLcontext *ctx, 870 struct gl_renderbuffer *rb, 871 GLuint n, GLint x, GLint y, 872 const GLchan color[4], 873 const GLubyte mask[]) 874{ 875 LPWORD lpw; 876 WORD pixel; 877 GLuint i; 878 WMesaContext pwc = wmesa_context(ctx); 879 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 880 (void) ctx; 881 lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x; 882 y=FLIP(y); 883 pixel = BGR16(color[RCOMP], color[GCOMP], color[BCOMP]); 884 if (mask) { 885 for (i=0; i<n; i++) 886 if (mask[i]) 887 lpw[i] = pixel; 888 } 889 else 890 for (i=0; i<n; i++) 891 *lpw++ = pixel; 892 893} 894 895/* Write an array of RGBA pixels with a boolean mask. */ 896static void write_rgba_pixels_16(const GLcontext *ctx, 897 struct gl_renderbuffer *rb, 898 GLuint n, const GLint x[], const GLint y[], 899 const GLubyte rgba[][4], 900 const GLubyte mask[]) 901{ 902 GLuint i; 903 WMesaContext pwc = wmesa_context(ctx); 904 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 905 (void) ctx; 906 for (i=0; i<n; i++) 907 if (mask[i]) 908 WMSETPIXEL16(pwfb, FLIP(y[i]), x[i], 909 rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); 910} 911 912/* 913 * Write an array of pixels with a boolean mask. The current color 914 * is used for all pixels. 915 */ 916static void write_mono_rgba_pixels_16(const GLcontext *ctx, 917 struct gl_renderbuffer *rb, 918 GLuint n, 919 const GLint x[], const GLint y[], 920 const GLchan color[4], 921 const GLubyte mask[]) 922{ 923 GLuint i; 924 WMesaContext pwc = wmesa_context(ctx); 925 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 926 (void) ctx; 927 for (i=0; i<n; i++) 928 if (mask[i]) 929 WMSETPIXEL16(pwfb, FLIP(y[i]),x[i],color[RCOMP], 930 color[GCOMP], color[BCOMP]); 931} 932 933/* Read a horizontal span of color pixels. */ 934static void read_rgba_span_16(const GLcontext *ctx, 935 struct gl_renderbuffer *rb, 936 GLuint n, GLint x, GLint y, 937 GLubyte rgba[][4] ) 938{ 939 GLuint i, pixel; 940 LPWORD lpw; 941 WMesaContext pwc = wmesa_context(ctx); 942 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 943 944 y = FLIP(y); 945 lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x; 946 for (i=0; i<n; i++) { 947 pixel = lpw[i]; 948 /* Windows uses 5,5,5 for 16-bit */ 949 rgba[i][RCOMP] = (pixel & 0x7c00) >> 7; 950 rgba[i][GCOMP] = (pixel & 0x03e0) >> 2; 951 rgba[i][BCOMP] = (pixel & 0x001f) << 3; 952 rgba[i][ACOMP] = 255; 953 } 954} 955 956 957/* Read an array of color pixels. */ 958static void read_rgba_pixels_16(const GLcontext *ctx, 959 struct gl_renderbuffer *rb, 960 GLuint n, const GLint x[], const GLint y[], 961 GLubyte rgba[][4]) 962{ 963 GLuint i, pixel; 964 LPWORD lpw; 965 WMesaContext pwc = wmesa_context(ctx); 966 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 967 968 for (i=0; i<n; i++) { 969 GLint y2 = FLIP(y[i]); 970 lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y2)) + x[i]; 971 pixel = *lpw; 972 /* Windows uses 5,5,5 for 16-bit */ 973 rgba[i][RCOMP] = (pixel & 0x7c00) >> 7; 974 rgba[i][GCOMP] = (pixel & 0x03e0) >> 2; 975 rgba[i][BCOMP] = (pixel & 0x001f) << 3; 976 rgba[i][ACOMP] = 255; 977 } 978} 979 980 981 982 983/**********************************************************************/ 984/***** BUFFER Functions *****/ 985/**********************************************************************/ 986 987 988 989 990static void 991wmesa_delete_renderbuffer(struct gl_renderbuffer *rb) 992{ 993 _mesa_free(rb); 994} 995 996 997/** 998 * This is called by Mesa whenever it determines that the window size 999 * has changed. Do whatever's needed to cope with that. 1000 */ 1001static GLboolean 1002wmesa_renderbuffer_storage(GLcontext *ctx, 1003 struct gl_renderbuffer *rb, 1004 GLenum internalFormat, 1005 GLuint width, 1006 GLuint height) 1007{ 1008 rb->Width = width; 1009 rb->Height = height; 1010 return GL_TRUE; 1011} 1012 1013 1014/** 1015 * Plug in the Get/PutRow/Values functions for a renderbuffer depending 1016 * on if we're drawing to the front or back color buffer. 1017 */ 1018void wmesa_set_renderbuffer_funcs(struct gl_renderbuffer *rb, int pixelformat, 1019 int double_buffer) 1020{ 1021 if (double_buffer) { 1022 /* back buffer */ 1023 /* Picking the correct span functions is important because 1024 * the DIB was allocated with the indicated depth. */ 1025 switch(pixelformat) { 1026 case PF_5R6G5B: 1027 rb->PutRow = write_rgba_span_16; 1028 rb->PutRowRGB = write_rgb_span_16; 1029 rb->PutMonoRow = write_mono_rgba_span_16; 1030 rb->PutValues = write_rgba_pixels_16; 1031 rb->PutMonoValues = write_mono_rgba_pixels_16; 1032 rb->GetRow = read_rgba_span_16; 1033 rb->GetValues = read_rgba_pixels_16; 1034 rb->RedBits = 5; 1035 rb->GreenBits = 6; 1036 rb->BlueBits = 5; 1037 break; 1038 case PF_8R8G8B: 1039 rb->PutRow = write_rgba_span_32; 1040 rb->PutRowRGB = write_rgb_span_32; 1041 rb->PutMonoRow = write_mono_rgba_span_32; 1042 rb->PutValues = write_rgba_pixels_32; 1043 rb->PutMonoValues = write_mono_rgba_pixels_32; 1044 rb->GetRow = read_rgba_span_32; 1045 rb->GetValues = read_rgba_pixels_32; 1046 rb->RedBits = 8; 1047 rb->GreenBits = 8; 1048 rb->BlueBits = 8; 1049 break; 1050 default: 1051 break; 1052 } 1053 } 1054 else { 1055 /* front buffer (actual Windows window) */ 1056 rb->PutRow = write_rgba_span_front; 1057 rb->PutRowRGB = write_rgb_span_front; 1058 rb->PutMonoRow = write_mono_rgba_span_front; 1059 rb->PutValues = write_rgba_pixels_front; 1060 rb->PutMonoValues = write_mono_rgba_pixels_front; 1061 rb->GetRow = read_rgba_span_front; 1062 rb->GetValues = read_rgba_pixels_front; 1063 rb->RedBits = 8; /* XXX fix these (565?) */ 1064 rb->GreenBits = 8; 1065 rb->BlueBits = 8; 1066 } 1067} 1068 1069/** 1070 * Called by ctx->Driver.ResizeBuffers() 1071 * Resize the front/back colorbuffers to match the latest window size. 1072 */ 1073static void 1074wmesa_resize_buffers(GLcontext *ctx, GLframebuffer *buffer, 1075 GLuint width, GLuint height) 1076{ 1077 WMesaContext pwc = wmesa_context(ctx); 1078 WMesaFramebuffer pwfb = wmesa_framebuffer(buffer); 1079 1080 if (pwfb->Base.Width != width || pwfb->Base.Height != height) { 1081 /* Realloc back buffer */ 1082 if (ctx->Visual.doubleBufferMode == 1) { 1083 wmDeleteBackingStore(pwfb); 1084 wmCreateBackingStore(pwfb, width, height); 1085 } 1086 } 1087 _mesa_resize_framebuffer(ctx, buffer, width, height); 1088} 1089 1090 1091/** 1092 * Called by glViewport. 1093 * This is a good time for us to poll the current window size and adjust 1094 * our renderbuffers to match the current window size. 1095 * Remember, we have no opportunity to respond to conventional 1096 * resize events since the driver has no event loop. 1097 * Thus, we poll. 1098 * MakeCurrent also ends up making a call here, so that ensures 1099 * we get the viewport set correctly, even if the app does not call 1100 * glViewport and relies on the defaults. 1101 */ 1102static void wmesa_viewport(GLcontext *ctx, 1103 GLint x, GLint y, 1104 GLsizei width, GLsizei height) 1105{ 1106 WMesaContext pwc = wmesa_context(ctx); 1107 GLuint new_width, new_height; 1108 1109 wmesa_get_buffer_size(ctx->WinSysDrawBuffer, &new_width, &new_height); 1110 1111 /** 1112 * Resize buffers if the window size changed. 1113 */ 1114 wmesa_resize_buffers(ctx, ctx->WinSysDrawBuffer, new_width, new_height); 1115 ctx->NewState |= _NEW_BUFFERS; /* to update scissor / window bounds */ 1116} 1117 1118 1119 1120 1121/** 1122 * Called when the driver should update it's state, based on the new_state 1123 * flags. 1124 */ 1125static void wmesa_update_state(GLcontext *ctx, GLuint new_state) 1126{ 1127 _swrast_InvalidateState(ctx, new_state); 1128 _swsetup_InvalidateState(ctx, new_state); 1129 _vbo_InvalidateState(ctx, new_state); 1130 _tnl_InvalidateState(ctx, new_state); 1131 1132 /* TODO - This code is not complete yet because I 1133 * don't know what to do for all state updates. 1134 */ 1135 1136 if (new_state & _NEW_BUFFERS) { 1137 } 1138} 1139 1140 1141 1142 1143 1144/**********************************************************************/ 1145/***** WMESA Functions *****/ 1146/**********************************************************************/ 1147 1148WMesaContext WMesaCreateContext(HDC hDC, 1149 HPALETTE* Pal, 1150 GLboolean rgb_flag, 1151 GLboolean db_flag, 1152 GLboolean alpha_flag) 1153{ 1154 WMesaContext c; 1155 struct dd_function_table functions; 1156 GLint red_bits, green_bits, blue_bits, alpha_bits; 1157 GLcontext *ctx; 1158 GLvisual *visual; 1159 1160 (void) Pal; 1161 1162 /* Indexed mode not supported */ 1163 if (!rgb_flag) 1164 return NULL; 1165 1166 /* Allocate wmesa context */ 1167 c = CALLOC_STRUCT(wmesa_context); 1168 if (!c) 1169 return NULL; 1170 1171#if 0 1172 /* I do not understand this contributed code */ 1173 /* Support memory and device contexts */ 1174 if(WindowFromDC(hDC) != NULL) { 1175 c->hDC = GetDC(WindowFromDC(hDC)); /* huh ???? */ 1176 } 1177 else { 1178 c->hDC = hDC; 1179 } 1180#else 1181 c->hDC = hDC; 1182#endif 1183 1184 /* Get data for visual */ 1185 /* Dealing with this is actually a bit of overkill because Mesa will end 1186 * up treating all color component size requests less than 8 by using 1187 * a single byte per channel. In addition, the interface to the span 1188 * routines passes colors as an entire byte per channel anyway, so there 1189 * is nothing to be saved by telling the visual to be 16 bits if the device 1190 * is 16 bits. That is, Mesa is going to compute colors down to 8 bits per 1191 * channel anyway. 1192 * But we go through the motions here anyway. 1193 */ 1194 switch (GetDeviceCaps(c->hDC, BITSPIXEL)) { 1195 case 16: 1196 red_bits = green_bits = blue_bits = 5; 1197 alpha_bits = 0; 1198 break; 1199 default: 1200 red_bits = green_bits = blue_bits = 8; 1201 alpha_bits = 8; 1202 break; 1203 } 1204 /* Create visual based on flags */ 1205 visual = _mesa_create_visual(rgb_flag, 1206 db_flag, /* db_flag */ 1207 GL_FALSE, /* stereo */ 1208 red_bits, green_bits, blue_bits, /* color RGB */ 1209 alpha_flag ? alpha_bits : 0, /* color A */ 1210 0, /* index bits */ 1211 DEFAULT_SOFTWARE_DEPTH_BITS, /* depth_bits */ 1212 8, /* stencil_bits */ 1213 16,16,16, /* accum RGB */ 1214 alpha_flag ? 16 : 0, /* accum A */ 1215 1); /* num samples */ 1216 1217 if (!visual) { 1218 _mesa_free(c); 1219 return NULL; 1220 } 1221 1222 /* Set up driver functions */ 1223 _mesa_init_driver_functions(&functions); 1224 functions.GetString = wmesa_get_string; 1225 functions.UpdateState = wmesa_update_state; 1226 functions.GetBufferSize = wmesa_get_buffer_size; 1227 functions.Flush = wmesa_flush; 1228 functions.Clear = clear; 1229 functions.ClearIndex = clear_index; 1230 functions.ClearColor = clear_color; 1231 functions.ResizeBuffers = wmesa_resize_buffers; 1232 functions.Viewport = wmesa_viewport; 1233 1234 /* initialize the Mesa context data */ 1235 ctx = &c->gl_ctx; 1236 _mesa_initialize_context(ctx, visual, NULL, &functions, (void *)c); 1237 1238 _mesa_enable_sw_extensions(ctx); 1239 _mesa_enable_1_3_extensions(ctx); 1240 _mesa_enable_1_4_extensions(ctx); 1241 _mesa_enable_1_5_extensions(ctx); 1242 _mesa_enable_2_0_extensions(ctx); 1243 _mesa_enable_2_1_extensions(ctx); 1244 1245 /* Initialize the software rasterizer and helper modules. */ 1246 if (!_swrast_CreateContext(ctx) || 1247 !_vbo_CreateContext(ctx) || 1248 !_tnl_CreateContext(ctx) || 1249 !_swsetup_CreateContext(ctx)) { 1250 _mesa_free_context_data(ctx); 1251 _mesa_free(c); 1252 return NULL; 1253 } 1254 _swsetup_Wakeup(ctx); 1255 TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline; 1256 1257 return c; 1258} 1259 1260 1261void WMesaDestroyContext( WMesaContext pwc ) 1262{ 1263 GLcontext *ctx = &pwc->gl_ctx; 1264 WMesaFramebuffer pwfb; 1265 GET_CURRENT_CONTEXT(cur_ctx); 1266 1267 if (cur_ctx == ctx) { 1268 /* unbind current if deleting current context */ 1269 WMesaMakeCurrent(NULL, NULL); 1270 } 1271 1272 /* clean up frame buffer resources */ 1273 pwfb = wmesa_lookup_framebuffer(pwc->hDC); 1274 if (pwfb) { 1275 if (ctx->Visual.doubleBufferMode == 1) 1276 wmDeleteBackingStore(pwfb); 1277 wmesa_free_framebuffer(pwc->hDC); 1278 } 1279 1280 /* Release for device, not memory contexts */ 1281 if (WindowFromDC(pwc->hDC) != NULL) 1282 { 1283 ReleaseDC(WindowFromDC(pwc->hDC), pwc->hDC); 1284 } 1285 DeleteObject(pwc->clearPen); 1286 DeleteObject(pwc->clearBrush); 1287 1288 _swsetup_DestroyContext(ctx); 1289 _tnl_DestroyContext(ctx); 1290 _vbo_DestroyContext(ctx); 1291 _swrast_DestroyContext(ctx); 1292 1293 _mesa_free_context_data(ctx); 1294 _mesa_free(pwc); 1295} 1296 1297 1298/** 1299 * Create a new color renderbuffer. 1300 */ 1301struct gl_renderbuffer * 1302wmesa_new_renderbuffer(void) 1303{ 1304 struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer); 1305 if (!rb) 1306 return NULL; 1307 1308 _mesa_init_renderbuffer(rb, (GLuint)0); 1309 1310 rb->_BaseFormat = GL_RGBA; 1311 rb->InternalFormat = GL_RGBA; 1312 rb->DataType = CHAN_TYPE; 1313 rb->Delete = wmesa_delete_renderbuffer; 1314 rb->AllocStorage = wmesa_renderbuffer_storage; 1315 return rb; 1316} 1317 1318 1319void WMesaMakeCurrent(WMesaContext c, HDC hdc) 1320{ 1321 WMesaFramebuffer pwfb; 1322 1323 { 1324 /* return if already current */ 1325 GET_CURRENT_CONTEXT(ctx); 1326 WMesaContext pwc = wmesa_context(ctx); 1327 if (pwc && c == pwc && pwc->hDC == hdc) 1328 return; 1329 } 1330 1331 pwfb = wmesa_lookup_framebuffer(hdc); 1332 1333 /* Lazy creation of framebuffers */ 1334 if (c && !pwfb && hdc) { 1335 struct gl_renderbuffer *rb; 1336 GLvisual *visual = &c->gl_ctx.Visual; 1337 GLuint width, height; 1338 1339 get_window_size(hdc, &width, &height); 1340 1341 c->clearPen = CreatePen(PS_SOLID, 1, 0); 1342 c->clearBrush = CreateSolidBrush(0); 1343 1344 pwfb = wmesa_new_framebuffer(hdc, visual); 1345 1346 /* Create back buffer if double buffered */ 1347 if (visual->doubleBufferMode == 1) { 1348 wmCreateBackingStore(pwfb, width, height); 1349 } 1350 1351 /* make render buffers */ 1352 if (visual->doubleBufferMode == 1) { 1353 rb = wmesa_new_renderbuffer(); 1354 _mesa_add_renderbuffer(&pwfb->Base, BUFFER_BACK_LEFT, rb); 1355 wmesa_set_renderbuffer_funcs(rb, pwfb->pixelformat, 1); 1356 } 1357 rb = wmesa_new_renderbuffer(); 1358 _mesa_add_renderbuffer(&pwfb->Base, BUFFER_FRONT_LEFT, rb); 1359 wmesa_set_renderbuffer_funcs(rb, pwfb->pixelformat, 0); 1360 1361 /* Let Mesa own the Depth, Stencil, and Accum buffers */ 1362 _mesa_add_soft_renderbuffers(&pwfb->Base, 1363 GL_FALSE, /* color */ 1364 visual->depthBits > 0, 1365 visual->stencilBits > 0, 1366 visual->accumRedBits > 0, 1367 visual->alphaBits >0, 1368 GL_FALSE); 1369 } 1370 1371 if (c && pwfb) 1372 _mesa_make_current(&c->gl_ctx, &pwfb->Base, &pwfb->Base); 1373 else 1374 _mesa_make_current(NULL, NULL, NULL); 1375} 1376 1377 1378void WMesaSwapBuffers( HDC hdc ) 1379{ 1380 GET_CURRENT_CONTEXT(ctx); 1381 WMesaContext pwc = wmesa_context(ctx); 1382 WMesaFramebuffer pwfb = wmesa_lookup_framebuffer(hdc); 1383 1384 if (!pwfb) { 1385 _mesa_problem(NULL, "wmesa: swapbuffers on unknown hdc"); 1386 return; 1387 } 1388 1389 /* If we're swapping the buffer associated with the current context 1390 * we have to flush any pending rendering commands first. 1391 */ 1392 if (pwc->hDC == hdc) { 1393 _mesa_notifySwapBuffers(ctx); 1394 1395 BitBlt(pwfb->hDC, 0, 0, pwfb->Base.Width, pwfb->Base.Height, 1396 pwfb->dib_hDC, 0, 0, SRCCOPY); 1397 } 1398 else { 1399 /* XXX for now only allow swapping current window */ 1400 _mesa_problem(NULL, "wmesa: can't swap non-current window"); 1401 } 1402} 1403 1404/* This is hopefully a temporary hack to define some needed dispatch 1405 * table entries. Hopefully, I'll find a better solution. The 1406 * dispatch table generation scripts ought to be making these dummy 1407 * stubs as well. */ 1408#if !defined(__MINGW32__) || !defined(GL_NO_STDCALL) 1409void gl_dispatch_stub_543(void){} 1410void gl_dispatch_stub_544(void){} 1411void gl_dispatch_stub_545(void){} 1412void gl_dispatch_stub_546(void){} 1413void gl_dispatch_stub_547(void){} 1414void gl_dispatch_stub_548(void){} 1415void gl_dispatch_stub_549(void){} 1416void gl_dispatch_stub_550(void){} 1417void gl_dispatch_stub_551(void){} 1418void gl_dispatch_stub_552(void){} 1419void gl_dispatch_stub_553(void){} 1420void gl_dispatch_stub_554(void){} 1421void gl_dispatch_stub_555(void){} 1422void gl_dispatch_stub_556(void){} 1423void gl_dispatch_stub_557(void){} 1424void gl_dispatch_stub_558(void){} 1425void gl_dispatch_stub_559(void){} 1426void gl_dispatch_stub_560(void){} 1427void gl_dispatch_stub_561(void){} 1428void gl_dispatch_stub_565(void){} 1429void gl_dispatch_stub_566(void){} 1430void gl_dispatch_stub_577(void){} 1431void gl_dispatch_stub_578(void){} 1432void gl_dispatch_stub_603(void){} 1433void gl_dispatch_stub_645(void){} 1434void gl_dispatch_stub_646(void){} 1435void gl_dispatch_stub_647(void){} 1436void gl_dispatch_stub_648(void){} 1437void gl_dispatch_stub_649(void){} 1438void gl_dispatch_stub_650(void){} 1439void gl_dispatch_stub_651(void){} 1440void gl_dispatch_stub_652(void){} 1441void gl_dispatch_stub_653(void){} 1442void gl_dispatch_stub_734(void){} 1443void gl_dispatch_stub_735(void){} 1444void gl_dispatch_stub_736(void){} 1445void gl_dispatch_stub_737(void){} 1446void gl_dispatch_stub_738(void){} 1447void gl_dispatch_stub_745(void){} 1448void gl_dispatch_stub_746(void){} 1449void gl_dispatch_stub_760(void){} 1450void gl_dispatch_stub_761(void){} 1451void gl_dispatch_stub_766(void){} 1452void gl_dispatch_stub_767(void){} 1453void gl_dispatch_stub_768(void){} 1454 1455void gl_dispatch_stub_562(void){} 1456void gl_dispatch_stub_563(void){} 1457void gl_dispatch_stub_564(void){} 1458void gl_dispatch_stub_567(void){} 1459void gl_dispatch_stub_568(void){} 1460void gl_dispatch_stub_569(void){} 1461void gl_dispatch_stub_580(void){} 1462void gl_dispatch_stub_581(void){} 1463void gl_dispatch_stub_606(void){} 1464void gl_dispatch_stub_654(void){} 1465void gl_dispatch_stub_655(void){} 1466void gl_dispatch_stub_656(void){} 1467void gl_dispatch_stub_739(void){} 1468void gl_dispatch_stub_740(void){} 1469void gl_dispatch_stub_741(void){} 1470void gl_dispatch_stub_748(void){} 1471void gl_dispatch_stub_749(void){} 1472void gl_dispatch_stub_769(void){} 1473void gl_dispatch_stub_770(void){} 1474void gl_dispatch_stub_771(void){} 1475 1476#endif 1477