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