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