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