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