wmesa.c revision 157eeb5c3b1ed16d67247f41e83dad3cda6e31ef
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 WMesaFramebuffer pwfb = wmesa_lookup_framebuffer(pwc->hDC); 463 CONST BITMAPINFO bmi= 464 { 465 { 466 sizeof(BITMAPINFOHEADER), 467 n, 1, 1, 32, BI_RGB, 0, 1, 1, 0, 0 468 } 469 }; 470 HBITMAP bmp=0; 471 HDC mdc=0; 472 typedef union 473 { 474 unsigned i; 475 struct { 476 unsigned b:8, g:8, r:8, a:8; 477 }; 478 } BGRA; 479 BGRA *bgra, c; 480 int i; 481 482 if (n < 16) { // the value 16 is just guessed 483 y=FLIP(y); 484 if (mask) { 485 for (i=0; i<n; i++) 486 if (mask[i]) 487 SetPixel(pwc->hDC, x+i, y, 488 RGB(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP])); 489 } 490 else { 491 for (i=0; i<n; i++) 492 SetPixel(pwc->hDC, x+i, y, 493 RGB(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP])); 494 } 495 } 496 else { 497 if (!pwfb) { 498 _mesa_problem(NULL, "wmesa: write_rgba_span_front on unknown hdc"); 499 return; 500 } 501 bgra=malloc(n*sizeof(BGRA)); 502 if (!bgra) { 503 _mesa_problem(NULL, "wmesa: write_rgba_span_front: out of memory"); 504 return; 505 } 506 c.a=0; 507 if (mask) { 508 for (i=0; i<n; i++) { 509 if (mask[i]) { 510 c.r=rgba[i][RCOMP]; 511 c.g=rgba[i][GCOMP]; 512 c.b=rgba[i][BCOMP]; 513 c.a=rgba[i][ACOMP]; 514 bgra[i]=c; 515 } 516 else 517 bgra[i].i=0; 518 } 519 } 520 else { 521 for (i=0; i<n; i++) { 522 c.r=rgba[i][RCOMP]; 523 c.g=rgba[i][GCOMP]; 524 c.b=rgba[i][BCOMP]; 525 c.a=rgba[i][ACOMP]; 526 bgra[i]=c; 527 } 528 } 529 bmp=CreateBitmap(n, 1, 1, 32, bgra); 530 mdc=CreateCompatibleDC(pwfb->hDC); 531 SelectObject(mdc, bmp); 532 y=FLIP(y); 533 BitBlt(pwfb->hDC, x, y, n, 1, mdc, 0, 0, SRCCOPY); 534 SelectObject(mdc, 0); 535 DeleteObject(bmp); 536 DeleteDC(mdc); 537 free(bgra); 538 } 539} 540 541/* Write a horizontal span of RGB color pixels with a boolean mask. */ 542static void write_rgb_span_front(const GLcontext *ctx, 543 struct gl_renderbuffer *rb, 544 GLuint n, GLint x, GLint y, 545 const GLubyte rgb[][3], 546 const GLubyte mask[] ) 547{ 548 WMesaContext pwc = wmesa_context(ctx); 549 GLuint i; 550 551 (void) ctx; 552 y=FLIP(y); 553 if (mask) { 554 for (i=0; i<n; i++) 555 if (mask[i]) 556 SetPixel(pwc->hDC, x+i, y, RGB(rgb[i][RCOMP], rgb[i][GCOMP], 557 rgb[i][BCOMP])); 558 } 559 else { 560 for (i=0; i<n; i++) 561 SetPixel(pwc->hDC, x+i, y, RGB(rgb[i][RCOMP], rgb[i][GCOMP], 562 rgb[i][BCOMP])); 563 } 564 565} 566 567/* 568 * Write a horizontal span of pixels with a boolean mask. The current color 569 * is used for all pixels. 570 */ 571static void write_mono_rgba_span_front(const GLcontext *ctx, 572 struct gl_renderbuffer *rb, 573 GLuint n, GLint x, GLint y, 574 const GLchan color[4], 575 const GLubyte mask[]) 576{ 577 GLuint i; 578 WMesaContext pwc = wmesa_context(ctx); 579 COLORREF colorref; 580 581 (void) ctx; 582 colorref = RGB(color[RCOMP], color[GCOMP], color[BCOMP]); 583 y=FLIP(y); 584 if (mask) { 585 for (i=0; i<n; i++) 586 if (mask[i]) 587 SetPixel(pwc->hDC, x+i, y, colorref); 588 } 589 else 590 for (i=0; i<n; i++) 591 SetPixel(pwc->hDC, x+i, y, colorref); 592 593} 594 595/* Write an array of RGBA pixels with a boolean mask. */ 596static void write_rgba_pixels_front(const GLcontext *ctx, 597 struct gl_renderbuffer *rb, 598 GLuint n, 599 const GLint x[], const GLint y[], 600 const GLubyte rgba[][4], 601 const GLubyte mask[] ) 602{ 603 GLuint i; 604 WMesaContext pwc = wmesa_context(ctx); 605 (void) ctx; 606 for (i=0; i<n; i++) 607 if (mask[i]) 608 SetPixel(pwc->hDC, x[i], FLIP(y[i]), 609 RGB(rgba[i][RCOMP], rgba[i][GCOMP], 610 rgba[i][BCOMP])); 611} 612 613 614 615/* 616 * Write an array of pixels with a boolean mask. The current color 617 * is used for all pixels. 618 */ 619static void write_mono_rgba_pixels_front(const GLcontext *ctx, 620 struct gl_renderbuffer *rb, 621 GLuint n, 622 const GLint x[], const GLint y[], 623 const GLchan color[4], 624 const GLubyte mask[] ) 625{ 626 GLuint i; 627 WMesaContext pwc = wmesa_context(ctx); 628 COLORREF colorref; 629 (void) ctx; 630 colorref = RGB(color[RCOMP], color[GCOMP], color[BCOMP]); 631 for (i=0; i<n; i++) 632 if (mask[i]) 633 SetPixel(pwc->hDC, x[i], FLIP(y[i]), colorref); 634} 635 636/* Read a horizontal span of color pixels. */ 637static void read_rgba_span_front(const GLcontext *ctx, 638 struct gl_renderbuffer *rb, 639 GLuint n, GLint x, GLint y, 640 GLubyte rgba[][4] ) 641{ 642 WMesaContext pwc = wmesa_context(ctx); 643 GLuint i; 644 COLORREF Color; 645 y = FLIP(y); 646 for (i=0; i<n; i++) { 647 Color = GetPixel(pwc->hDC, x+i, y); 648 rgba[i][RCOMP] = GetRValue(Color); 649 rgba[i][GCOMP] = GetGValue(Color); 650 rgba[i][BCOMP] = GetBValue(Color); 651 rgba[i][ACOMP] = 255; 652 } 653} 654 655 656/* Read an array of color pixels. */ 657static void read_rgba_pixels_front(const GLcontext *ctx, 658 struct gl_renderbuffer *rb, 659 GLuint n, const GLint x[], const GLint y[], 660 GLubyte rgba[][4]) 661{ 662 WMesaContext pwc = wmesa_context(ctx); 663 GLuint i; 664 COLORREF Color; 665 for (i=0; i<n; i++) { 666 GLint y2 = FLIP(y[i]); 667 Color = GetPixel(pwc->hDC, x[i], y2); 668 rgba[i][RCOMP] = GetRValue(Color); 669 rgba[i][GCOMP] = GetGValue(Color); 670 rgba[i][BCOMP] = GetBValue(Color); 671 rgba[i][ACOMP] = 255; 672 } 673} 674 675/*********************************************************************/ 676 677/* DOUBLE BUFFER 32-bit */ 678 679#define WMSETPIXEL32(pwc, y, x, r, g, b) { \ 680LPDWORD lpdw = ((LPDWORD)((pwc)->pbPixels + (pwc)->ScanWidth * (y)) + (x)); \ 681*lpdw = BGR32((r),(g),(b)); } 682 683 684 685/* Write a horizontal span of RGBA color pixels with a boolean mask. */ 686static void write_rgba_span_32(const GLcontext *ctx, 687 struct gl_renderbuffer *rb, 688 GLuint n, GLint x, GLint y, 689 const GLubyte rgba[][4], 690 const GLubyte mask[] ) 691{ 692 WMesaContext pwc = wmesa_context(ctx); 693 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 694 GLuint i; 695 LPDWORD lpdw; 696 697 (void) ctx; 698 699 y=FLIP(y); 700 lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x; 701 if (mask) { 702 for (i=0; i<n; i++) 703 if (mask[i]) 704 lpdw[i] = BGR32(rgba[i][RCOMP], rgba[i][GCOMP], 705 rgba[i][BCOMP]); 706 } 707 else { 708 for (i=0; i<n; i++) 709 *lpdw++ = BGR32(rgba[i][RCOMP], rgba[i][GCOMP], 710 rgba[i][BCOMP]); 711 } 712} 713 714 715/* Write a horizontal span of RGB color pixels with a boolean mask. */ 716static void write_rgb_span_32(const GLcontext *ctx, 717 struct gl_renderbuffer *rb, 718 GLuint n, GLint x, GLint y, 719 const GLubyte rgb[][3], 720 const GLubyte mask[] ) 721{ 722 WMesaContext pwc = wmesa_context(ctx); 723 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 724 GLuint i; 725 LPDWORD lpdw; 726 727 (void) ctx; 728 729 y=FLIP(y); 730 lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x; 731 if (mask) { 732 for (i=0; i<n; i++) 733 if (mask[i]) 734 lpdw[i] = BGR32(rgb[i][RCOMP], rgb[i][GCOMP], 735 rgb[i][BCOMP]); 736 } 737 else { 738 for (i=0; i<n; i++) 739 *lpdw++ = BGR32(rgb[i][RCOMP], rgb[i][GCOMP], 740 rgb[i][BCOMP]); 741 } 742} 743 744/* 745 * Write a horizontal span of pixels with a boolean mask. The current color 746 * is used for all pixels. 747 */ 748static void write_mono_rgba_span_32(const GLcontext *ctx, 749 struct gl_renderbuffer *rb, 750 GLuint n, GLint x, GLint y, 751 const GLchan color[4], 752 const GLubyte mask[]) 753{ 754 LPDWORD lpdw; 755 DWORD pixel; 756 GLuint i; 757 WMesaContext pwc = wmesa_context(ctx); 758 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 759 lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x; 760 y=FLIP(y); 761 pixel = BGR32(color[RCOMP], color[GCOMP], color[BCOMP]); 762 if (mask) { 763 for (i=0; i<n; i++) 764 if (mask[i]) 765 lpdw[i] = pixel; 766 } 767 else 768 for (i=0; i<n; i++) 769 *lpdw++ = pixel; 770 771} 772 773/* Write an array of RGBA pixels with a boolean mask. */ 774static void write_rgba_pixels_32(const GLcontext *ctx, 775 struct gl_renderbuffer *rb, 776 GLuint n, const GLint x[], const GLint y[], 777 const GLubyte rgba[][4], 778 const GLubyte mask[]) 779{ 780 GLuint i; 781 WMesaContext pwc = wmesa_context(ctx); 782 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 783 for (i=0; i<n; i++) 784 if (mask[i]) 785 WMSETPIXEL32(pwfb, FLIP(y[i]), x[i], 786 rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); 787} 788 789/* 790 * Write an array of pixels with a boolean mask. The current color 791 * is used for all pixels. 792 */ 793static void write_mono_rgba_pixels_32(const GLcontext *ctx, 794 struct gl_renderbuffer *rb, 795 GLuint n, 796 const GLint x[], const GLint y[], 797 const GLchan color[4], 798 const GLubyte mask[]) 799{ 800 GLuint i; 801 WMesaContext pwc = wmesa_context(ctx); 802 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 803 for (i=0; i<n; i++) 804 if (mask[i]) 805 WMSETPIXEL32(pwfb, FLIP(y[i]),x[i],color[RCOMP], 806 color[GCOMP], color[BCOMP]); 807} 808 809/* Read a horizontal span of color pixels. */ 810static void read_rgba_span_32(const GLcontext *ctx, 811 struct gl_renderbuffer *rb, 812 GLuint n, GLint x, GLint y, 813 GLubyte rgba[][4] ) 814{ 815 GLuint i; 816 DWORD pixel; 817 LPDWORD lpdw; 818 WMesaContext pwc = wmesa_context(ctx); 819 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 820 821 y = FLIP(y); 822 lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x; 823 for (i=0; i<n; i++) { 824 pixel = lpdw[i]; 825 rgba[i][RCOMP] = (pixel & 0x00ff0000) >> 16; 826 rgba[i][GCOMP] = (pixel & 0x0000ff00) >> 8; 827 rgba[i][BCOMP] = (pixel & 0x000000ff); 828 rgba[i][ACOMP] = 255; 829 } 830} 831 832 833/* Read an array of color pixels. */ 834static void read_rgba_pixels_32(const GLcontext *ctx, 835 struct gl_renderbuffer *rb, 836 GLuint n, const GLint x[], const GLint y[], 837 GLubyte rgba[][4]) 838{ 839 GLuint i; 840 DWORD pixel; 841 LPDWORD lpdw; 842 WMesaContext pwc = wmesa_context(ctx); 843 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 844 845 for (i=0; i<n; i++) { 846 GLint y2 = FLIP(y[i]); 847 lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y2)) + x[i]; 848 pixel = *lpdw; 849 rgba[i][RCOMP] = (pixel & 0x00ff0000) >> 16; 850 rgba[i][GCOMP] = (pixel & 0x0000ff00) >> 8; 851 rgba[i][BCOMP] = (pixel & 0x000000ff); 852 rgba[i][ACOMP] = 255; 853 } 854} 855 856 857/*********************************************************************/ 858 859/* DOUBLE BUFFER 16-bit */ 860 861#define WMSETPIXEL16(pwc, y, x, r, g, b) { \ 862LPWORD lpw = ((LPWORD)((pwc)->pbPixels + (pwc)->ScanWidth * (y)) + (x)); \ 863*lpw = BGR16((r),(g),(b)); } 864 865 866 867/* Write a horizontal span of RGBA color pixels with a boolean mask. */ 868static void write_rgba_span_16(const GLcontext *ctx, 869 struct gl_renderbuffer *rb, 870 GLuint n, GLint x, GLint y, 871 const GLubyte rgba[][4], 872 const GLubyte mask[] ) 873{ 874 WMesaContext pwc = wmesa_context(ctx); 875 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 876 GLuint i; 877 LPWORD lpw; 878 879 (void) ctx; 880 881 y=FLIP(y); 882 lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x; 883 if (mask) { 884 for (i=0; i<n; i++) 885 if (mask[i]) 886 lpw[i] = BGR16(rgba[i][RCOMP], rgba[i][GCOMP], 887 rgba[i][BCOMP]); 888 } 889 else { 890 for (i=0; i<n; i++) 891 *lpw++ = BGR16(rgba[i][RCOMP], rgba[i][GCOMP], 892 rgba[i][BCOMP]); 893 } 894} 895 896 897/* Write a horizontal span of RGB color pixels with a boolean mask. */ 898static void write_rgb_span_16(const GLcontext *ctx, 899 struct gl_renderbuffer *rb, 900 GLuint n, GLint x, GLint y, 901 const GLubyte rgb[][3], 902 const GLubyte mask[] ) 903{ 904 WMesaContext pwc = wmesa_context(ctx); 905 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 906 GLuint i; 907 LPWORD lpw; 908 909 (void) ctx; 910 911 y=FLIP(y); 912 lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x; 913 if (mask) { 914 for (i=0; i<n; i++) 915 if (mask[i]) 916 lpw[i] = BGR16(rgb[i][RCOMP], rgb[i][GCOMP], 917 rgb[i][BCOMP]); 918 } 919 else { 920 for (i=0; i<n; i++) 921 *lpw++ = BGR16(rgb[i][RCOMP], rgb[i][GCOMP], 922 rgb[i][BCOMP]); 923 } 924} 925 926/* 927 * Write a horizontal span of pixels with a boolean mask. The current color 928 * is used for all pixels. 929 */ 930static void write_mono_rgba_span_16(const GLcontext *ctx, 931 struct gl_renderbuffer *rb, 932 GLuint n, GLint x, GLint y, 933 const GLchan color[4], 934 const GLubyte mask[]) 935{ 936 LPWORD lpw; 937 WORD pixel; 938 GLuint i; 939 WMesaContext pwc = wmesa_context(ctx); 940 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 941 (void) ctx; 942 lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x; 943 y=FLIP(y); 944 pixel = BGR16(color[RCOMP], color[GCOMP], color[BCOMP]); 945 if (mask) { 946 for (i=0; i<n; i++) 947 if (mask[i]) 948 lpw[i] = pixel; 949 } 950 else 951 for (i=0; i<n; i++) 952 *lpw++ = pixel; 953 954} 955 956/* Write an array of RGBA pixels with a boolean mask. */ 957static void write_rgba_pixels_16(const GLcontext *ctx, 958 struct gl_renderbuffer *rb, 959 GLuint n, const GLint x[], const GLint y[], 960 const GLubyte rgba[][4], 961 const GLubyte mask[]) 962{ 963 GLuint i; 964 WMesaContext pwc = wmesa_context(ctx); 965 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 966 (void) ctx; 967 for (i=0; i<n; i++) 968 if (mask[i]) 969 WMSETPIXEL16(pwfb, FLIP(y[i]), x[i], 970 rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); 971} 972 973/* 974 * Write an array of pixels with a boolean mask. The current color 975 * is used for all pixels. 976 */ 977static void write_mono_rgba_pixels_16(const GLcontext *ctx, 978 struct gl_renderbuffer *rb, 979 GLuint n, 980 const GLint x[], const GLint y[], 981 const GLchan color[4], 982 const GLubyte mask[]) 983{ 984 GLuint i; 985 WMesaContext pwc = wmesa_context(ctx); 986 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 987 (void) ctx; 988 for (i=0; i<n; i++) 989 if (mask[i]) 990 WMSETPIXEL16(pwfb, FLIP(y[i]),x[i],color[RCOMP], 991 color[GCOMP], color[BCOMP]); 992} 993 994/* Read a horizontal span of color pixels. */ 995static void read_rgba_span_16(const GLcontext *ctx, 996 struct gl_renderbuffer *rb, 997 GLuint n, GLint x, GLint y, 998 GLubyte rgba[][4] ) 999{ 1000 GLuint i, pixel; 1001 LPWORD lpw; 1002 WMesaContext pwc = wmesa_context(ctx); 1003 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 1004 1005 y = FLIP(y); 1006 lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x; 1007 for (i=0; i<n; i++) { 1008 pixel = lpw[i]; 1009 /* Windows uses 5,5,5 for 16-bit */ 1010 rgba[i][RCOMP] = (pixel & 0x7c00) >> 7; 1011 rgba[i][GCOMP] = (pixel & 0x03e0) >> 2; 1012 rgba[i][BCOMP] = (pixel & 0x001f) << 3; 1013 rgba[i][ACOMP] = 255; 1014 } 1015} 1016 1017 1018/* Read an array of color pixels. */ 1019static void read_rgba_pixels_16(const GLcontext *ctx, 1020 struct gl_renderbuffer *rb, 1021 GLuint n, const GLint x[], const GLint y[], 1022 GLubyte rgba[][4]) 1023{ 1024 GLuint i, pixel; 1025 LPWORD lpw; 1026 WMesaContext pwc = wmesa_context(ctx); 1027 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); 1028 1029 for (i=0; i<n; i++) { 1030 GLint y2 = FLIP(y[i]); 1031 lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y2)) + x[i]; 1032 pixel = *lpw; 1033 /* Windows uses 5,5,5 for 16-bit */ 1034 rgba[i][RCOMP] = (pixel & 0x7c00) >> 7; 1035 rgba[i][GCOMP] = (pixel & 0x03e0) >> 2; 1036 rgba[i][BCOMP] = (pixel & 0x001f) << 3; 1037 rgba[i][ACOMP] = 255; 1038 } 1039} 1040 1041 1042 1043 1044/**********************************************************************/ 1045/***** BUFFER Functions *****/ 1046/**********************************************************************/ 1047 1048 1049 1050 1051static void 1052wmesa_delete_renderbuffer(struct gl_renderbuffer *rb) 1053{ 1054 _mesa_free(rb); 1055} 1056 1057 1058/** 1059 * This is called by Mesa whenever it determines that the window size 1060 * has changed. Do whatever's needed to cope with that. 1061 */ 1062static GLboolean 1063wmesa_renderbuffer_storage(GLcontext *ctx, 1064 struct gl_renderbuffer *rb, 1065 GLenum internalFormat, 1066 GLuint width, 1067 GLuint height) 1068{ 1069 rb->Width = width; 1070 rb->Height = height; 1071 return GL_TRUE; 1072} 1073 1074 1075/** 1076 * Plug in the Get/PutRow/Values functions for a renderbuffer depending 1077 * on if we're drawing to the front or back color buffer. 1078 */ 1079void wmesa_set_renderbuffer_funcs(struct gl_renderbuffer *rb, int pixelformat, 1080 int double_buffer) 1081{ 1082 if (double_buffer) { 1083 /* back buffer */ 1084 /* Picking the correct span functions is important because 1085 * the DIB was allocated with the indicated depth. */ 1086 switch(pixelformat) { 1087 case PF_5R6G5B: 1088 rb->PutRow = write_rgba_span_16; 1089 rb->PutRowRGB = write_rgb_span_16; 1090 rb->PutMonoRow = write_mono_rgba_span_16; 1091 rb->PutValues = write_rgba_pixels_16; 1092 rb->PutMonoValues = write_mono_rgba_pixels_16; 1093 rb->GetRow = read_rgba_span_16; 1094 rb->GetValues = read_rgba_pixels_16; 1095 rb->RedBits = 5; 1096 rb->GreenBits = 6; 1097 rb->BlueBits = 5; 1098 break; 1099 case PF_8R8G8B: 1100 rb->PutRow = write_rgba_span_32; 1101 rb->PutRowRGB = write_rgb_span_32; 1102 rb->PutMonoRow = write_mono_rgba_span_32; 1103 rb->PutValues = write_rgba_pixels_32; 1104 rb->PutMonoValues = write_mono_rgba_pixels_32; 1105 rb->GetRow = read_rgba_span_32; 1106 rb->GetValues = read_rgba_pixels_32; 1107 rb->RedBits = 8; 1108 rb->GreenBits = 8; 1109 rb->BlueBits = 8; 1110 break; 1111 default: 1112 break; 1113 } 1114 } 1115 else { 1116 /* front buffer (actual Windows window) */ 1117 rb->PutRow = write_rgba_span_front; 1118 rb->PutRowRGB = write_rgb_span_front; 1119 rb->PutMonoRow = write_mono_rgba_span_front; 1120 rb->PutValues = write_rgba_pixels_front; 1121 rb->PutMonoValues = write_mono_rgba_pixels_front; 1122 rb->GetRow = read_rgba_span_front; 1123 rb->GetValues = read_rgba_pixels_front; 1124 rb->RedBits = 8; /* XXX fix these (565?) */ 1125 rb->GreenBits = 8; 1126 rb->BlueBits = 8; 1127 } 1128} 1129 1130/** 1131 * Called by ctx->Driver.ResizeBuffers() 1132 * Resize the front/back colorbuffers to match the latest window size. 1133 */ 1134static void 1135wmesa_resize_buffers(GLcontext *ctx, GLframebuffer *buffer, 1136 GLuint width, GLuint height) 1137{ 1138 WMesaContext pwc = wmesa_context(ctx); 1139 WMesaFramebuffer pwfb = wmesa_framebuffer(buffer); 1140 1141 if (pwfb->Base.Width != width || pwfb->Base.Height != height) { 1142 /* Realloc back buffer */ 1143 if (ctx->Visual.doubleBufferMode == 1) { 1144 wmDeleteBackingStore(pwfb); 1145 wmCreateBackingStore(pwfb, width, height); 1146 } 1147 } 1148 _mesa_resize_framebuffer(ctx, buffer, width, height); 1149} 1150 1151 1152/** 1153 * Called by glViewport. 1154 * This is a good time for us to poll the current window size and adjust 1155 * our renderbuffers to match the current window size. 1156 * Remember, we have no opportunity to respond to conventional 1157 * resize events since the driver has no event loop. 1158 * Thus, we poll. 1159 * MakeCurrent also ends up making a call here, so that ensures 1160 * we get the viewport set correctly, even if the app does not call 1161 * glViewport and relies on the defaults. 1162 */ 1163static void wmesa_viewport(GLcontext *ctx, 1164 GLint x, GLint y, 1165 GLsizei width, GLsizei height) 1166{ 1167 WMesaContext pwc = wmesa_context(ctx); 1168 GLuint new_width, new_height; 1169 1170 wmesa_get_buffer_size(ctx->WinSysDrawBuffer, &new_width, &new_height); 1171 1172 /** 1173 * Resize buffers if the window size changed. 1174 */ 1175 wmesa_resize_buffers(ctx, ctx->WinSysDrawBuffer, new_width, new_height); 1176 ctx->NewState |= _NEW_BUFFERS; /* to update scissor / window bounds */ 1177} 1178 1179 1180 1181 1182/** 1183 * Called when the driver should update it's state, based on the new_state 1184 * flags. 1185 */ 1186static void wmesa_update_state(GLcontext *ctx, GLuint new_state) 1187{ 1188 _swrast_InvalidateState(ctx, new_state); 1189 _swsetup_InvalidateState(ctx, new_state); 1190 _vbo_InvalidateState(ctx, new_state); 1191 _tnl_InvalidateState(ctx, new_state); 1192 1193 /* TODO - This code is not complete yet because I 1194 * don't know what to do for all state updates. 1195 */ 1196 1197 if (new_state & _NEW_BUFFERS) { 1198 } 1199} 1200 1201 1202 1203 1204 1205/**********************************************************************/ 1206/***** WMESA Functions *****/ 1207/**********************************************************************/ 1208 1209WMesaContext WMesaCreateContext(HDC hDC, 1210 HPALETTE* Pal, 1211 GLboolean rgb_flag, 1212 GLboolean db_flag, 1213 GLboolean alpha_flag) 1214{ 1215 WMesaContext c; 1216 struct dd_function_table functions; 1217 GLint red_bits, green_bits, blue_bits, alpha_bits; 1218 GLcontext *ctx; 1219 GLvisual *visual; 1220 1221 (void) Pal; 1222 1223 /* Indexed mode not supported */ 1224 if (!rgb_flag) 1225 return NULL; 1226 1227 /* Allocate wmesa context */ 1228 c = CALLOC_STRUCT(wmesa_context); 1229 if (!c) 1230 return NULL; 1231 1232#if 0 1233 /* I do not understand this contributed code */ 1234 /* Support memory and device contexts */ 1235 if(WindowFromDC(hDC) != NULL) { 1236 c->hDC = GetDC(WindowFromDC(hDC)); /* huh ???? */ 1237 } 1238 else { 1239 c->hDC = hDC; 1240 } 1241#else 1242 c->hDC = hDC; 1243#endif 1244 1245 /* Get data for visual */ 1246 /* Dealing with this is actually a bit of overkill because Mesa will end 1247 * up treating all color component size requests less than 8 by using 1248 * a single byte per channel. In addition, the interface to the span 1249 * routines passes colors as an entire byte per channel anyway, so there 1250 * is nothing to be saved by telling the visual to be 16 bits if the device 1251 * is 16 bits. That is, Mesa is going to compute colors down to 8 bits per 1252 * channel anyway. 1253 * But we go through the motions here anyway. 1254 */ 1255 switch (GetDeviceCaps(c->hDC, BITSPIXEL)) { 1256 case 16: 1257 red_bits = green_bits = blue_bits = 5; 1258 alpha_bits = 0; 1259 break; 1260 default: 1261 red_bits = green_bits = blue_bits = 8; 1262 alpha_bits = 8; 1263 break; 1264 } 1265 /* Create visual based on flags */ 1266 visual = _mesa_create_visual(rgb_flag, 1267 db_flag, /* db_flag */ 1268 GL_FALSE, /* stereo */ 1269 red_bits, green_bits, blue_bits, /* color RGB */ 1270 alpha_flag ? alpha_bits : 0, /* color A */ 1271 0, /* index bits */ 1272 DEFAULT_SOFTWARE_DEPTH_BITS, /* depth_bits */ 1273 8, /* stencil_bits */ 1274 16,16,16, /* accum RGB */ 1275 alpha_flag ? 16 : 0, /* accum A */ 1276 1); /* num samples */ 1277 1278 if (!visual) { 1279 _mesa_free(c); 1280 return NULL; 1281 } 1282 1283 /* Set up driver functions */ 1284 _mesa_init_driver_functions(&functions); 1285 functions.GetString = wmesa_get_string; 1286 functions.UpdateState = wmesa_update_state; 1287 functions.GetBufferSize = wmesa_get_buffer_size; 1288 functions.Flush = wmesa_flush; 1289 functions.Clear = clear; 1290 functions.ClearIndex = clear_index; 1291 functions.ClearColor = clear_color; 1292 functions.ResizeBuffers = wmesa_resize_buffers; 1293 functions.Viewport = wmesa_viewport; 1294 1295 /* initialize the Mesa context data */ 1296 ctx = &c->gl_ctx; 1297 _mesa_initialize_context(ctx, visual, NULL, &functions, (void *)c); 1298 1299 _mesa_enable_sw_extensions(ctx); 1300 _mesa_enable_1_3_extensions(ctx); 1301 _mesa_enable_1_4_extensions(ctx); 1302 _mesa_enable_1_5_extensions(ctx); 1303 _mesa_enable_2_0_extensions(ctx); 1304 _mesa_enable_2_1_extensions(ctx); 1305 1306 /* Initialize the software rasterizer and helper modules. */ 1307 if (!_swrast_CreateContext(ctx) || 1308 !_vbo_CreateContext(ctx) || 1309 !_tnl_CreateContext(ctx) || 1310 !_swsetup_CreateContext(ctx)) { 1311 _mesa_free_context_data(ctx); 1312 _mesa_free(c); 1313 return NULL; 1314 } 1315 _swsetup_Wakeup(ctx); 1316 TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline; 1317 1318 return c; 1319} 1320 1321 1322void WMesaDestroyContext( WMesaContext pwc ) 1323{ 1324 GLcontext *ctx = &pwc->gl_ctx; 1325 WMesaFramebuffer pwfb; 1326 GET_CURRENT_CONTEXT(cur_ctx); 1327 1328 if (cur_ctx == ctx) { 1329 /* unbind current if deleting current context */ 1330 WMesaMakeCurrent(NULL, NULL); 1331 } 1332 1333 /* clean up frame buffer resources */ 1334 pwfb = wmesa_lookup_framebuffer(pwc->hDC); 1335 if (pwfb) { 1336 if (ctx->Visual.doubleBufferMode == 1) 1337 wmDeleteBackingStore(pwfb); 1338 wmesa_free_framebuffer(pwc->hDC); 1339 } 1340 1341 /* Release for device, not memory contexts */ 1342 if (WindowFromDC(pwc->hDC) != NULL) 1343 { 1344 ReleaseDC(WindowFromDC(pwc->hDC), pwc->hDC); 1345 } 1346 DeleteObject(pwc->clearPen); 1347 DeleteObject(pwc->clearBrush); 1348 1349 _swsetup_DestroyContext(ctx); 1350 _tnl_DestroyContext(ctx); 1351 _vbo_DestroyContext(ctx); 1352 _swrast_DestroyContext(ctx); 1353 1354 _mesa_free_context_data(ctx); 1355 _mesa_free(pwc); 1356} 1357 1358 1359/** 1360 * Create a new color renderbuffer. 1361 */ 1362struct gl_renderbuffer * 1363wmesa_new_renderbuffer(void) 1364{ 1365 struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer); 1366 if (!rb) 1367 return NULL; 1368 1369 _mesa_init_renderbuffer(rb, (GLuint)0); 1370 1371 rb->_BaseFormat = GL_RGBA; 1372 rb->InternalFormat = GL_RGBA; 1373 rb->DataType = CHAN_TYPE; 1374 rb->Delete = wmesa_delete_renderbuffer; 1375 rb->AllocStorage = wmesa_renderbuffer_storage; 1376 return rb; 1377} 1378 1379 1380void WMesaMakeCurrent(WMesaContext c, HDC hdc) 1381{ 1382 WMesaFramebuffer pwfb; 1383 1384 { 1385 /* return if already current */ 1386 GET_CURRENT_CONTEXT(ctx); 1387 WMesaContext pwc = wmesa_context(ctx); 1388 if (pwc && c == pwc && pwc->hDC == hdc) 1389 return; 1390 } 1391 1392 pwfb = wmesa_lookup_framebuffer(hdc); 1393 1394 /* Lazy creation of framebuffers */ 1395 if (c && !pwfb && hdc) { 1396 struct gl_renderbuffer *rb; 1397 GLvisual *visual = &c->gl_ctx.Visual; 1398 GLuint width, height; 1399 1400 get_window_size(hdc, &width, &height); 1401 1402 c->clearPen = CreatePen(PS_SOLID, 1, 0); 1403 c->clearBrush = CreateSolidBrush(0); 1404 1405 pwfb = wmesa_new_framebuffer(hdc, visual); 1406 1407 /* Create back buffer if double buffered */ 1408 if (visual->doubleBufferMode == 1) { 1409 wmCreateBackingStore(pwfb, width, height); 1410 } 1411 1412 /* make render buffers */ 1413 if (visual->doubleBufferMode == 1) { 1414 rb = wmesa_new_renderbuffer(); 1415 _mesa_add_renderbuffer(&pwfb->Base, BUFFER_BACK_LEFT, rb); 1416 wmesa_set_renderbuffer_funcs(rb, pwfb->pixelformat, 1); 1417 } 1418 rb = wmesa_new_renderbuffer(); 1419 _mesa_add_renderbuffer(&pwfb->Base, BUFFER_FRONT_LEFT, rb); 1420 wmesa_set_renderbuffer_funcs(rb, pwfb->pixelformat, 0); 1421 1422 /* Let Mesa own the Depth, Stencil, and Accum buffers */ 1423 _mesa_add_soft_renderbuffers(&pwfb->Base, 1424 GL_FALSE, /* color */ 1425 visual->depthBits > 0, 1426 visual->stencilBits > 0, 1427 visual->accumRedBits > 0, 1428 visual->alphaBits >0, 1429 GL_FALSE); 1430 } 1431 1432 if (c && pwfb) 1433 _mesa_make_current(&c->gl_ctx, &pwfb->Base, &pwfb->Base); 1434 else 1435 _mesa_make_current(NULL, NULL, NULL); 1436} 1437 1438 1439void WMesaSwapBuffers( HDC hdc ) 1440{ 1441 GET_CURRENT_CONTEXT(ctx); 1442 WMesaContext pwc = wmesa_context(ctx); 1443 WMesaFramebuffer pwfb = wmesa_lookup_framebuffer(hdc); 1444 1445 if (!pwfb) { 1446 _mesa_problem(NULL, "wmesa: swapbuffers on unknown hdc"); 1447 return; 1448 } 1449 1450 /* If we're swapping the buffer associated with the current context 1451 * we have to flush any pending rendering commands first. 1452 */ 1453 if (pwc->hDC == hdc) { 1454 _mesa_notifySwapBuffers(ctx); 1455 1456 BitBlt(pwfb->hDC, 0, 0, pwfb->Base.Width, pwfb->Base.Height, 1457 pwfb->dib_hDC, 0, 0, SRCCOPY); 1458 } 1459 else { 1460 /* XXX for now only allow swapping current window */ 1461 _mesa_problem(NULL, "wmesa: can't swap non-current window"); 1462 } 1463} 1464 1465void WMesaShareLists(WMesaContext ctx_to_share, WMesaContext ctx) 1466{ 1467 _mesa_share_state(&ctx->gl_ctx, &ctx_to_share->gl_ctx); 1468} 1469 1470/* This is hopefully a temporary hack to define some needed dispatch 1471 * table entries. Hopefully, I'll find a better solution. The 1472 * dispatch table generation scripts ought to be making these dummy 1473 * stubs as well. */ 1474#if !defined(__MINGW32__) || !defined(GL_NO_STDCALL) 1475void gl_dispatch_stub_543(void){} 1476void gl_dispatch_stub_544(void){} 1477void gl_dispatch_stub_545(void){} 1478void gl_dispatch_stub_546(void){} 1479void gl_dispatch_stub_547(void){} 1480void gl_dispatch_stub_548(void){} 1481void gl_dispatch_stub_549(void){} 1482void gl_dispatch_stub_550(void){} 1483void gl_dispatch_stub_551(void){} 1484void gl_dispatch_stub_552(void){} 1485void gl_dispatch_stub_553(void){} 1486void gl_dispatch_stub_554(void){} 1487void gl_dispatch_stub_555(void){} 1488void gl_dispatch_stub_556(void){} 1489void gl_dispatch_stub_557(void){} 1490void gl_dispatch_stub_558(void){} 1491void gl_dispatch_stub_559(void){} 1492void gl_dispatch_stub_560(void){} 1493void gl_dispatch_stub_561(void){} 1494void gl_dispatch_stub_565(void){} 1495void gl_dispatch_stub_566(void){} 1496void gl_dispatch_stub_577(void){} 1497void gl_dispatch_stub_578(void){} 1498void gl_dispatch_stub_603(void){} 1499void gl_dispatch_stub_645(void){} 1500void gl_dispatch_stub_646(void){} 1501void gl_dispatch_stub_647(void){} 1502void gl_dispatch_stub_648(void){} 1503void gl_dispatch_stub_649(void){} 1504void gl_dispatch_stub_650(void){} 1505void gl_dispatch_stub_651(void){} 1506void gl_dispatch_stub_652(void){} 1507void gl_dispatch_stub_653(void){} 1508void gl_dispatch_stub_734(void){} 1509void gl_dispatch_stub_735(void){} 1510void gl_dispatch_stub_736(void){} 1511void gl_dispatch_stub_737(void){} 1512void gl_dispatch_stub_738(void){} 1513void gl_dispatch_stub_745(void){} 1514void gl_dispatch_stub_746(void){} 1515void gl_dispatch_stub_760(void){} 1516void gl_dispatch_stub_761(void){} 1517void gl_dispatch_stub_766(void){} 1518void gl_dispatch_stub_767(void){} 1519void gl_dispatch_stub_768(void){} 1520 1521void gl_dispatch_stub_562(void){} 1522void gl_dispatch_stub_563(void){} 1523void gl_dispatch_stub_564(void){} 1524void gl_dispatch_stub_567(void){} 1525void gl_dispatch_stub_568(void){} 1526void gl_dispatch_stub_569(void){} 1527void gl_dispatch_stub_580(void){} 1528void gl_dispatch_stub_581(void){} 1529void gl_dispatch_stub_606(void){} 1530void gl_dispatch_stub_654(void){} 1531void gl_dispatch_stub_655(void){} 1532void gl_dispatch_stub_656(void){} 1533void gl_dispatch_stub_739(void){} 1534void gl_dispatch_stub_740(void){} 1535void gl_dispatch_stub_741(void){} 1536void gl_dispatch_stub_748(void){} 1537void gl_dispatch_stub_749(void){} 1538void gl_dispatch_stub_769(void){} 1539void gl_dispatch_stub_770(void){} 1540void gl_dispatch_stub_771(void){} 1541 1542#endif 1543