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