stw_context.c revision 0c6a2c78fdd8b4ae620a9f449cab65c4be21a9a1
1/************************************************************************** 2 * 3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28#include <windows.h> 29 30#define WGL_WGLEXT_PROTOTYPES 31 32#include <GL/gl.h> 33#include <GL/wglext.h> 34 35#include "pipe/p_compiler.h" 36#include "pipe/p_context.h" 37#include "pipe/p_state.h" 38#include "util/u_memory.h" 39#include "util/u_atomic.h" 40#include "state_tracker/st_api.h" 41 42#include "stw_icd.h" 43#include "stw_device.h" 44#include "stw_winsys.h" 45#include "stw_framebuffer.h" 46#include "stw_pixelformat.h" 47#include "stw_context.h" 48#include "stw_tls.h" 49 50 51static INLINE struct stw_context * 52stw_current_context(void) 53{ 54 struct st_context_iface *st; 55 56 st = (stw_dev) ? stw_dev->stapi->get_current(stw_dev->stapi) : NULL; 57 58 return (struct stw_context *) ((st) ? st->st_manager_private : NULL); 59} 60 61BOOL APIENTRY 62DrvCopyContext( 63 DHGLRC dhrcSource, 64 DHGLRC dhrcDest, 65 UINT fuMask ) 66{ 67 struct stw_context *src; 68 struct stw_context *dst; 69 BOOL ret = FALSE; 70 71 if (!stw_dev) 72 return FALSE; 73 74 pipe_mutex_lock( stw_dev->ctx_mutex ); 75 76 src = stw_lookup_context_locked( dhrcSource ); 77 dst = stw_lookup_context_locked( dhrcDest ); 78 79 if (src && dst) { 80 /* FIXME */ 81 assert(0); 82 (void) src; 83 (void) dst; 84 (void) fuMask; 85 } 86 87 pipe_mutex_unlock( stw_dev->ctx_mutex ); 88 89 return ret; 90} 91 92BOOL APIENTRY 93DrvShareLists( 94 DHGLRC dhglrc1, 95 DHGLRC dhglrc2 ) 96{ 97 struct stw_context *ctx1; 98 struct stw_context *ctx2; 99 BOOL ret = FALSE; 100 101 if (!stw_dev) 102 return FALSE; 103 104 pipe_mutex_lock( stw_dev->ctx_mutex ); 105 106 ctx1 = stw_lookup_context_locked( dhglrc1 ); 107 ctx2 = stw_lookup_context_locked( dhglrc2 ); 108 109 if (ctx1 && ctx2 && ctx2->st->share) 110 ret = ctx2->st->share(ctx2->st, ctx1->st); 111 112 pipe_mutex_unlock( stw_dev->ctx_mutex ); 113 114 return ret; 115} 116 117DHGLRC APIENTRY 118DrvCreateContext( 119 HDC hdc ) 120{ 121 return DrvCreateLayerContext( hdc, 0 ); 122} 123 124DHGLRC APIENTRY 125DrvCreateLayerContext( 126 HDC hdc, 127 INT iLayerPlane ) 128{ 129 return stw_create_context_attribs(hdc, iLayerPlane, 0, 1, 0, 0, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB); 130} 131 132DHGLRC 133stw_create_context_attribs( 134 HDC hdc, 135 INT iLayerPlane, 136 DHGLRC hShareContext, 137 int majorVersion, int minorVersion, 138 int contextFlags, int profileMask) 139{ 140 int iPixelFormat; 141 const struct stw_pixelformat_info *pfi; 142 struct st_context_attribs attribs; 143 struct stw_context *ctx = NULL; 144 struct stw_context *shareCtx = NULL; 145 146 if (!stw_dev) 147 return 0; 148 149 if (iLayerPlane != 0) 150 return 0; 151 152 iPixelFormat = GetPixelFormat(hdc); 153 if(!iPixelFormat) 154 return 0; 155 156 pfi = stw_pixelformat_get_info( iPixelFormat - 1 ); 157 158 if (hShareContext != 0) { 159 pipe_mutex_lock( stw_dev->ctx_mutex ); 160 shareCtx = stw_lookup_context_locked( hShareContext ); 161 pipe_mutex_unlock( stw_dev->ctx_mutex ); 162 } 163 164 ctx = CALLOC_STRUCT( stw_context ); 165 if (ctx == NULL) 166 goto no_ctx; 167 168 ctx->hdc = hdc; 169 ctx->iPixelFormat = iPixelFormat; 170 171 memset(&attribs, 0, sizeof(attribs)); 172 attribs.profile = ST_PROFILE_DEFAULT; 173 attribs.visual = pfi->stvis; 174 attribs.major = majorVersion; 175 attribs.minor = minorVersion; 176 if (contextFlags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) 177 attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE; 178 if (contextFlags & WGL_CONTEXT_DEBUG_BIT_ARB) 179 attribs.flags |= ST_CONTEXT_FLAG_DEBUG; 180 if (profileMask & WGL_CONTEXT_CORE_PROFILE_BIT_ARB) 181 attribs.flags |= ST_CONTEXT_FLAG_CORE_PROFILE; 182 if (profileMask & WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB) 183 attribs.flags |= ST_CONTEXT_FLAG_COMPATIBLE_PROFILE; 184 185 ctx->st = stw_dev->stapi->create_context(stw_dev->stapi, 186 stw_dev->smapi, &attribs, shareCtx ? shareCtx->st : NULL); 187 if (ctx->st == NULL) 188 goto no_st_ctx; 189 190 ctx->st->st_manager_private = (void *) ctx; 191 192 pipe_mutex_lock( stw_dev->ctx_mutex ); 193 ctx->dhglrc = handle_table_add(stw_dev->ctx_table, ctx); 194 pipe_mutex_unlock( stw_dev->ctx_mutex ); 195 if (!ctx->dhglrc) 196 goto no_hglrc; 197 198 return ctx->dhglrc; 199 200no_hglrc: 201 ctx->st->destroy(ctx->st); 202no_st_ctx: 203 FREE(ctx); 204no_ctx: 205 return 0; 206} 207 208BOOL APIENTRY 209DrvDeleteContext( 210 DHGLRC dhglrc ) 211{ 212 struct stw_context *ctx ; 213 BOOL ret = FALSE; 214 215 if (!stw_dev) 216 return FALSE; 217 218 pipe_mutex_lock( stw_dev->ctx_mutex ); 219 ctx = stw_lookup_context_locked(dhglrc); 220 handle_table_remove(stw_dev->ctx_table, dhglrc); 221 pipe_mutex_unlock( stw_dev->ctx_mutex ); 222 223 if (ctx) { 224 struct stw_context *curctx = stw_current_context(); 225 226 /* Unbind current if deleting current context. */ 227 if (curctx == ctx) 228 stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL); 229 230 ctx->st->destroy(ctx->st); 231 FREE(ctx); 232 233 ret = TRUE; 234 } 235 236 return ret; 237} 238 239BOOL APIENTRY 240DrvReleaseContext( 241 DHGLRC dhglrc ) 242{ 243 struct stw_context *ctx; 244 245 if (!stw_dev) 246 return FALSE; 247 248 pipe_mutex_lock( stw_dev->ctx_mutex ); 249 ctx = stw_lookup_context_locked( dhglrc ); 250 pipe_mutex_unlock( stw_dev->ctx_mutex ); 251 252 if (!ctx) 253 return FALSE; 254 255 /* The expectation is that ctx is the same context which is 256 * current for this thread. We should check that and return False 257 * if not the case. 258 */ 259 if (ctx != stw_current_context()) 260 return FALSE; 261 262 if (stw_make_current( NULL, 0 ) == FALSE) 263 return FALSE; 264 265 return TRUE; 266} 267 268 269DHGLRC 270stw_get_current_context( void ) 271{ 272 struct stw_context *ctx; 273 274 ctx = stw_current_context(); 275 if(!ctx) 276 return 0; 277 278 return ctx->dhglrc; 279} 280 281HDC 282stw_get_current_dc( void ) 283{ 284 struct stw_context *ctx; 285 286 ctx = stw_current_context(); 287 if(!ctx) 288 return NULL; 289 290 return ctx->hdc; 291} 292 293BOOL 294stw_make_current( 295 HDC hdc, 296 DHGLRC dhglrc ) 297{ 298 struct stw_context *curctx = NULL; 299 struct stw_context *ctx = NULL; 300 struct stw_framebuffer *fb = NULL; 301 BOOL ret = FALSE; 302 303 if (!stw_dev) 304 return FALSE; 305 306 curctx = stw_current_context(); 307 if (curctx != NULL) { 308 if (curctx->dhglrc == dhglrc) { 309 if (curctx->hdc == hdc) { 310 /* Return if already current. */ 311 return TRUE; 312 } 313 } else { 314 curctx->st->flush(curctx->st, ST_FLUSH_FRONT, NULL); 315 } 316 } 317 318 if (dhglrc) { 319 pipe_mutex_lock( stw_dev->ctx_mutex ); 320 ctx = stw_lookup_context_locked( dhglrc ); 321 pipe_mutex_unlock( stw_dev->ctx_mutex ); 322 if (!ctx) { 323 goto fail; 324 } 325 326 fb = stw_framebuffer_from_hdc( hdc ); 327 if (fb) { 328 stw_framebuffer_update(fb); 329 } 330 else { 331 /* Applications should call SetPixelFormat before creating a context, 332 * but not all do, and the opengl32 runtime seems to use a default pixel 333 * format in some cases, so we must create a framebuffer for those here 334 */ 335 int iPixelFormat = GetPixelFormat(hdc); 336 if (iPixelFormat) 337 fb = stw_framebuffer_create( hdc, iPixelFormat ); 338 if (!fb) 339 goto fail; 340 } 341 342 if (fb->iPixelFormat != ctx->iPixelFormat) { 343 SetLastError(ERROR_INVALID_PIXEL_FORMAT); 344 goto fail; 345 } 346 347 /* Bind the new framebuffer */ 348 ctx->hdc = hdc; 349 350 ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st, fb->stfb, fb->stfb); 351 stw_framebuffer_reference(&ctx->current_framebuffer, fb); 352 } else { 353 ret = stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL); 354 } 355 356fail: 357 358 if (fb) { 359 stw_framebuffer_release(fb); 360 } 361 362 /* On failure, make the thread's current rendering context not current 363 * before returning */ 364 if (!ret) { 365 stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL); 366 ctx = NULL; 367 } 368 369 /* Unreference the previous framebuffer if any. It must be done after 370 * make_current, as it can be referenced inside. 371 */ 372 if (curctx && curctx != ctx) { 373 stw_framebuffer_reference(&curctx->current_framebuffer, NULL); 374 } 375 376 return ret; 377} 378 379/** 380 * Flush the current context if it is bound to the framebuffer. 381 */ 382void 383stw_flush_current_locked( struct stw_framebuffer *fb ) 384{ 385 struct stw_context *ctx = stw_current_context(); 386 387 if (ctx && ctx->current_framebuffer == fb) { 388 ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL); 389 } 390} 391 392/** 393 * Notify the current context that the framebuffer has become invalid. 394 */ 395void 396stw_notify_current_locked( struct stw_framebuffer *fb ) 397{ 398 p_atomic_inc(&fb->stfb->stamp); 399} 400 401/** 402 * Although WGL allows different dispatch entrypoints per context 403 */ 404static const GLCLTPROCTABLE cpt = 405{ 406 OPENGL_VERSION_110_ENTRIES, 407 { 408 &glNewList, 409 &glEndList, 410 &glCallList, 411 &glCallLists, 412 &glDeleteLists, 413 &glGenLists, 414 &glListBase, 415 &glBegin, 416 &glBitmap, 417 &glColor3b, 418 &glColor3bv, 419 &glColor3d, 420 &glColor3dv, 421 &glColor3f, 422 &glColor3fv, 423 &glColor3i, 424 &glColor3iv, 425 &glColor3s, 426 &glColor3sv, 427 &glColor3ub, 428 &glColor3ubv, 429 &glColor3ui, 430 &glColor3uiv, 431 &glColor3us, 432 &glColor3usv, 433 &glColor4b, 434 &glColor4bv, 435 &glColor4d, 436 &glColor4dv, 437 &glColor4f, 438 &glColor4fv, 439 &glColor4i, 440 &glColor4iv, 441 &glColor4s, 442 &glColor4sv, 443 &glColor4ub, 444 &glColor4ubv, 445 &glColor4ui, 446 &glColor4uiv, 447 &glColor4us, 448 &glColor4usv, 449 &glEdgeFlag, 450 &glEdgeFlagv, 451 &glEnd, 452 &glIndexd, 453 &glIndexdv, 454 &glIndexf, 455 &glIndexfv, 456 &glIndexi, 457 &glIndexiv, 458 &glIndexs, 459 &glIndexsv, 460 &glNormal3b, 461 &glNormal3bv, 462 &glNormal3d, 463 &glNormal3dv, 464 &glNormal3f, 465 &glNormal3fv, 466 &glNormal3i, 467 &glNormal3iv, 468 &glNormal3s, 469 &glNormal3sv, 470 &glRasterPos2d, 471 &glRasterPos2dv, 472 &glRasterPos2f, 473 &glRasterPos2fv, 474 &glRasterPos2i, 475 &glRasterPos2iv, 476 &glRasterPos2s, 477 &glRasterPos2sv, 478 &glRasterPos3d, 479 &glRasterPos3dv, 480 &glRasterPos3f, 481 &glRasterPos3fv, 482 &glRasterPos3i, 483 &glRasterPos3iv, 484 &glRasterPos3s, 485 &glRasterPos3sv, 486 &glRasterPos4d, 487 &glRasterPos4dv, 488 &glRasterPos4f, 489 &glRasterPos4fv, 490 &glRasterPos4i, 491 &glRasterPos4iv, 492 &glRasterPos4s, 493 &glRasterPos4sv, 494 &glRectd, 495 &glRectdv, 496 &glRectf, 497 &glRectfv, 498 &glRecti, 499 &glRectiv, 500 &glRects, 501 &glRectsv, 502 &glTexCoord1d, 503 &glTexCoord1dv, 504 &glTexCoord1f, 505 &glTexCoord1fv, 506 &glTexCoord1i, 507 &glTexCoord1iv, 508 &glTexCoord1s, 509 &glTexCoord1sv, 510 &glTexCoord2d, 511 &glTexCoord2dv, 512 &glTexCoord2f, 513 &glTexCoord2fv, 514 &glTexCoord2i, 515 &glTexCoord2iv, 516 &glTexCoord2s, 517 &glTexCoord2sv, 518 &glTexCoord3d, 519 &glTexCoord3dv, 520 &glTexCoord3f, 521 &glTexCoord3fv, 522 &glTexCoord3i, 523 &glTexCoord3iv, 524 &glTexCoord3s, 525 &glTexCoord3sv, 526 &glTexCoord4d, 527 &glTexCoord4dv, 528 &glTexCoord4f, 529 &glTexCoord4fv, 530 &glTexCoord4i, 531 &glTexCoord4iv, 532 &glTexCoord4s, 533 &glTexCoord4sv, 534 &glVertex2d, 535 &glVertex2dv, 536 &glVertex2f, 537 &glVertex2fv, 538 &glVertex2i, 539 &glVertex2iv, 540 &glVertex2s, 541 &glVertex2sv, 542 &glVertex3d, 543 &glVertex3dv, 544 &glVertex3f, 545 &glVertex3fv, 546 &glVertex3i, 547 &glVertex3iv, 548 &glVertex3s, 549 &glVertex3sv, 550 &glVertex4d, 551 &glVertex4dv, 552 &glVertex4f, 553 &glVertex4fv, 554 &glVertex4i, 555 &glVertex4iv, 556 &glVertex4s, 557 &glVertex4sv, 558 &glClipPlane, 559 &glColorMaterial, 560 &glCullFace, 561 &glFogf, 562 &glFogfv, 563 &glFogi, 564 &glFogiv, 565 &glFrontFace, 566 &glHint, 567 &glLightf, 568 &glLightfv, 569 &glLighti, 570 &glLightiv, 571 &glLightModelf, 572 &glLightModelfv, 573 &glLightModeli, 574 &glLightModeliv, 575 &glLineStipple, 576 &glLineWidth, 577 &glMaterialf, 578 &glMaterialfv, 579 &glMateriali, 580 &glMaterialiv, 581 &glPointSize, 582 &glPolygonMode, 583 &glPolygonStipple, 584 &glScissor, 585 &glShadeModel, 586 &glTexParameterf, 587 &glTexParameterfv, 588 &glTexParameteri, 589 &glTexParameteriv, 590 &glTexImage1D, 591 &glTexImage2D, 592 &glTexEnvf, 593 &glTexEnvfv, 594 &glTexEnvi, 595 &glTexEnviv, 596 &glTexGend, 597 &glTexGendv, 598 &glTexGenf, 599 &glTexGenfv, 600 &glTexGeni, 601 &glTexGeniv, 602 &glFeedbackBuffer, 603 &glSelectBuffer, 604 &glRenderMode, 605 &glInitNames, 606 &glLoadName, 607 &glPassThrough, 608 &glPopName, 609 &glPushName, 610 &glDrawBuffer, 611 &glClear, 612 &glClearAccum, 613 &glClearIndex, 614 &glClearColor, 615 &glClearStencil, 616 &glClearDepth, 617 &glStencilMask, 618 &glColorMask, 619 &glDepthMask, 620 &glIndexMask, 621 &glAccum, 622 &glDisable, 623 &glEnable, 624 &glFinish, 625 &glFlush, 626 &glPopAttrib, 627 &glPushAttrib, 628 &glMap1d, 629 &glMap1f, 630 &glMap2d, 631 &glMap2f, 632 &glMapGrid1d, 633 &glMapGrid1f, 634 &glMapGrid2d, 635 &glMapGrid2f, 636 &glEvalCoord1d, 637 &glEvalCoord1dv, 638 &glEvalCoord1f, 639 &glEvalCoord1fv, 640 &glEvalCoord2d, 641 &glEvalCoord2dv, 642 &glEvalCoord2f, 643 &glEvalCoord2fv, 644 &glEvalMesh1, 645 &glEvalPoint1, 646 &glEvalMesh2, 647 &glEvalPoint2, 648 &glAlphaFunc, 649 &glBlendFunc, 650 &glLogicOp, 651 &glStencilFunc, 652 &glStencilOp, 653 &glDepthFunc, 654 &glPixelZoom, 655 &glPixelTransferf, 656 &glPixelTransferi, 657 &glPixelStoref, 658 &glPixelStorei, 659 &glPixelMapfv, 660 &glPixelMapuiv, 661 &glPixelMapusv, 662 &glReadBuffer, 663 &glCopyPixels, 664 &glReadPixels, 665 &glDrawPixels, 666 &glGetBooleanv, 667 &glGetClipPlane, 668 &glGetDoublev, 669 &glGetError, 670 &glGetFloatv, 671 &glGetIntegerv, 672 &glGetLightfv, 673 &glGetLightiv, 674 &glGetMapdv, 675 &glGetMapfv, 676 &glGetMapiv, 677 &glGetMaterialfv, 678 &glGetMaterialiv, 679 &glGetPixelMapfv, 680 &glGetPixelMapuiv, 681 &glGetPixelMapusv, 682 &glGetPolygonStipple, 683 &glGetString, 684 &glGetTexEnvfv, 685 &glGetTexEnviv, 686 &glGetTexGendv, 687 &glGetTexGenfv, 688 &glGetTexGeniv, 689 &glGetTexImage, 690 &glGetTexParameterfv, 691 &glGetTexParameteriv, 692 &glGetTexLevelParameterfv, 693 &glGetTexLevelParameteriv, 694 &glIsEnabled, 695 &glIsList, 696 &glDepthRange, 697 &glFrustum, 698 &glLoadIdentity, 699 &glLoadMatrixf, 700 &glLoadMatrixd, 701 &glMatrixMode, 702 &glMultMatrixf, 703 &glMultMatrixd, 704 &glOrtho, 705 &glPopMatrix, 706 &glPushMatrix, 707 &glRotated, 708 &glRotatef, 709 &glScaled, 710 &glScalef, 711 &glTranslated, 712 &glTranslatef, 713 &glViewport, 714 &glArrayElement, 715 &glBindTexture, 716 &glColorPointer, 717 &glDisableClientState, 718 &glDrawArrays, 719 &glDrawElements, 720 &glEdgeFlagPointer, 721 &glEnableClientState, 722 &glIndexPointer, 723 &glIndexub, 724 &glIndexubv, 725 &glInterleavedArrays, 726 &glNormalPointer, 727 &glPolygonOffset, 728 &glTexCoordPointer, 729 &glVertexPointer, 730 &glAreTexturesResident, 731 &glCopyTexImage1D, 732 &glCopyTexImage2D, 733 &glCopyTexSubImage1D, 734 &glCopyTexSubImage2D, 735 &glDeleteTextures, 736 &glGenTextures, 737 &glGetPointerv, 738 &glIsTexture, 739 &glPrioritizeTextures, 740 &glTexSubImage1D, 741 &glTexSubImage2D, 742 &glPopClientAttrib, 743 &glPushClientAttrib 744 } 745}; 746 747PGLCLTPROCTABLE APIENTRY 748DrvSetContext( 749 HDC hdc, 750 DHGLRC dhglrc, 751 PFN_SETPROCTABLE pfnSetProcTable ) 752{ 753 PGLCLTPROCTABLE r = (PGLCLTPROCTABLE)&cpt; 754 755 if (!stw_make_current( hdc, dhglrc )) 756 r = NULL; 757 758 return r; 759} 760