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