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