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