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