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