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