swrast.c revision 529d1d720e1422bad1880ef33fae1c9423112d2e
1/* 2 * Copyright (C) 2008 George Sapountzis <gsap7@yahoo.gr> 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included 12 * in all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 */ 21 22/* 23 * DRI software rasterizer 24 * 25 * This is the mesa swrast module packaged into a DRI driver structure. 26 * 27 * The front-buffer is allocated by the loader. The loader provides read/write 28 * callbacks for access to the front-buffer. The driver uses a scratch row for 29 * front-buffer rendering to avoid repeated calls to the loader. 30 * 31 * The back-buffer is allocated by the driver and is private. 32 */ 33 34#include "main/context.h" 35#include "main/extensions.h" 36#include "main/framebuffer.h" 37#include "main/imports.h" 38#include "main/renderbuffer.h" 39#include "swrast/swrast.h" 40#include "swrast_setup/swrast_setup.h" 41#include "tnl/tnl.h" 42#include "tnl/t_context.h" 43#include "tnl/t_pipeline.h" 44#include "vbo/vbo.h" 45#include "drivers/common/driverfuncs.h" 46#include "utils.h" 47 48#include "swrast_priv.h" 49 50 51#define need_GL_VERSION_1_3 52#define need_GL_VERSION_1_4 53#define need_GL_VERSION_1_5 54#define need_GL_VERSION_2_0 55#define need_GL_VERSION_2_1 56 57/* sw extensions for imaging */ 58#define need_GL_EXT_blend_color 59#define need_GL_EXT_blend_minmax 60#define need_GL_EXT_convolution 61#define need_GL_EXT_histogram 62#define need_GL_SGI_color_table 63 64/* sw extensions not associated with some GL version */ 65#define need_GL_ARB_shader_objects 66#define need_GL_ARB_vertex_program 67#define need_GL_APPLE_vertex_array_object 68#define need_GL_ATI_fragment_shader 69#define need_GL_ATI_separate_stencil 70#define need_GL_EXT_depth_bounds_test 71#define need_GL_EXT_framebuffer_object 72#define need_GL_EXT_framebuffer_blit 73#define need_GL_EXT_gpu_program_parameters 74#define need_GL_EXT_paletted_texture 75#define need_GL_EXT_stencil_two_side 76#define need_GL_MESA_resize_buffers 77#define need_GL_NV_vertex_program 78#define need_GL_NV_fragment_program 79 80#include "extension_helper.h" 81 82const struct dri_extension card_extensions[] = 83{ 84 { "GL_VERSION_1_3", GL_VERSION_1_3_functions }, 85 { "GL_VERSION_1_4", GL_VERSION_1_4_functions }, 86 { "GL_VERSION_1_5", GL_VERSION_1_5_functions }, 87 { "GL_VERSION_2_0", GL_VERSION_2_0_functions }, 88 { "GL_VERSION_2_1", GL_VERSION_2_1_functions }, 89 90 { "GL_EXT_blend_color", GL_EXT_blend_color_functions }, 91 { "GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions }, 92 { "GL_EXT_convolution", GL_EXT_convolution_functions }, 93 { "GL_EXT_histogram", GL_EXT_histogram_functions }, 94 { "GL_SGI_color_table", GL_SGI_color_table_functions }, 95 96 { "GL_ARB_shader_objects", GL_ARB_shader_objects_functions }, 97 { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions }, 98 { "GL_APPLE_vertex_array_object", GL_APPLE_vertex_array_object_functions }, 99 { "GL_ATI_fragment_shader", GL_ATI_fragment_shader_functions }, 100 { "GL_ATI_separate_stencil", GL_ATI_separate_stencil_functions }, 101 { "GL_EXT_depth_bounds_test", GL_EXT_depth_bounds_test_functions }, 102 { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions }, 103 { "GL_EXT_framebuffer_blit", GL_EXT_framebuffer_blit_functions }, 104 { "GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions }, 105 { "GL_EXT_paletted_texture", GL_EXT_paletted_texture_functions }, 106 { "GL_EXT_stencil_two_side", GL_EXT_stencil_two_side_functions }, 107 { "GL_MESA_resize_buffers", GL_MESA_resize_buffers_functions }, 108 { "GL_NV_vertex_program", GL_NV_vertex_program_functions }, 109 { "GL_NV_fragment_program", GL_NV_fragment_program_functions }, 110 { NULL, NULL } 111}; 112 113 114/** 115 * Screen and config-related functions 116 */ 117 118static void 119setupLoaderExtensions(__DRIscreen *psp, 120 const __DRIextension **extensions) 121{ 122 int i; 123 124 for (i = 0; extensions[i]; i++) { 125 if (strcmp(extensions[i]->name, __DRI_SWRAST_LOADER) == 0) 126 psp->swrast_loader = (__DRIswrastLoaderExtension *) extensions[i]; 127 } 128} 129 130static const __DRIconfig ** 131swrastFillInModes(__DRIscreen *psp, 132 unsigned pixel_bits, unsigned depth_bits, 133 unsigned stencil_bits, GLboolean have_back_buffer) 134{ 135 __DRIconfig **configs; 136 unsigned depth_buffer_factor; 137 unsigned back_buffer_factor; 138 GLenum fb_format; 139 GLenum fb_type; 140 141 /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't 142 * support pageflipping at all. 143 */ 144 static const GLenum back_buffer_modes[] = { 145 GLX_NONE, GLX_SWAP_UNDEFINED_OML 146 }; 147 148 uint8_t depth_bits_array[4]; 149 uint8_t stencil_bits_array[4]; 150 151 depth_bits_array[0] = 0; 152 depth_bits_array[1] = 0; 153 depth_bits_array[2] = depth_bits; 154 depth_bits_array[3] = depth_bits; 155 156 /* Just like with the accumulation buffer, always provide some modes 157 * with a stencil buffer. 158 */ 159 stencil_bits_array[0] = 0; 160 stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits; 161 stencil_bits_array[2] = 0; 162 stencil_bits_array[3] = (stencil_bits == 0) ? 8 : stencil_bits; 163 164 depth_buffer_factor = 4; 165 back_buffer_factor = 2; 166 167 switch (pixel_bits) { 168 case 8: 169 fb_format = GL_RGB; 170 fb_type = GL_UNSIGNED_BYTE_2_3_3_REV; 171 break; 172 case 16: 173 fb_format = GL_RGB; 174 fb_type = GL_UNSIGNED_SHORT_5_6_5; 175 break; 176 case 24: 177 fb_format = GL_BGR; 178 fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; 179 break; 180 case 32: 181 fb_format = GL_BGRA; 182 fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; 183 break; 184 default: 185 fprintf(stderr, "[%s:%u] bad depth %d\n", __func__, __LINE__, 186 pixel_bits); 187 return NULL; 188 } 189 190 configs = driCreateConfigs(fb_format, fb_type, 191 depth_bits_array, stencil_bits_array, 192 depth_buffer_factor, back_buffer_modes, 193 back_buffer_factor); 194 if (configs == NULL) { 195 fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, 196 __LINE__); 197 return NULL; 198 } 199 200 return (const __DRIconfig **)configs; 201} 202 203static __DRIscreen * 204driCreateNewScreen(int scrn, const __DRIextension **extensions, 205 const __DRIconfig ***driver_configs, void *data) 206{ 207 static const __DRIextension *emptyExtensionList[] = { NULL }; 208 __DRIscreen *psp; 209 const __DRIconfig **configs8, **configs16, **configs24, **configs32; 210 211 (void) data; 212 213 TRACE; 214 215 psp = _mesa_calloc(sizeof(*psp)); 216 if (!psp) 217 return NULL; 218 219 setupLoaderExtensions(psp, extensions); 220 221 psp->num = scrn; 222 psp->extensions = emptyExtensionList; 223 224 configs8 = swrastFillInModes(psp, 8, 8, 0, 1); 225 configs16 = swrastFillInModes(psp, 16, 16, 0, 1); 226 configs24 = swrastFillInModes(psp, 24, 24, 8, 1); 227 configs32 = swrastFillInModes(psp, 32, 24, 8, 1); 228 229 configs16 = driConcatConfigs(configs8, configs16); 230 configs24 = driConcatConfigs(configs16, configs24); 231 *driver_configs = driConcatConfigs(configs24, configs32); 232 233 driInitExtensions( NULL, card_extensions, GL_FALSE ); 234 235 return psp; 236} 237 238static void driDestroyScreen(__DRIscreen *psp) 239{ 240 TRACE; 241 242 if (psp) { 243 _mesa_free(psp); 244 } 245} 246 247static const __DRIextension **driGetExtensions(__DRIscreen *psp) 248{ 249 TRACE; 250 251 return psp->extensions; 252} 253 254 255/** 256 * Framebuffer and renderbuffer-related functions. 257 */ 258 259static GLuint 260choose_pixel_format(const GLvisual *v) 261{ 262 if (v->rgbMode) { 263 int depth = v->rgbBits; 264 265 if (depth == 32 266 && v->redMask == 0xff0000 267 && v->greenMask == 0x00ff00 268 && v->blueMask == 0x0000ff) 269 return PF_A8R8G8B8; 270 else if (depth == 24 271 && v->redMask == 0xff0000 272 && v->greenMask == 0x00ff00 273 && v->blueMask == 0x0000ff) 274 return PF_X8R8G8B8; 275 else if (depth == 16 276 && v->redMask == 0xf800 277 && v->greenMask == 0x07e0 278 && v->blueMask == 0x001f) 279 return PF_R5G6B5; 280 else if (depth == 8 281 && v->redMask == 0x07 282 && v->greenMask == 0x38 283 && v->blueMask == 0xc0) 284 return PF_R3G3B2; 285 } 286 else { 287 if (v->indexBits == 8) 288 return PF_CI8; 289 } 290 291 _mesa_problem( NULL, "unexpected format in %s", __FUNCTION__ ); 292 return 0; 293} 294 295static void 296swrast_delete_renderbuffer(struct gl_renderbuffer *rb) 297{ 298 TRACE; 299 300 _mesa_free(rb->Data); 301 _mesa_free(rb); 302} 303 304static GLboolean 305swrast_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb, 306 GLenum internalFormat, GLuint width, GLuint height) 307{ 308 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); 309 unsigned mask = PITCH_ALIGN_BITS - 1; 310 311 TRACE; 312 313 rb->Data = NULL; 314 rb->Width = width; 315 rb->Height = height; 316 317 /* always pad to PITCH_ALIGN_BITS */ 318 xrb->pitch = ((width * xrb->bpp + mask) & ~mask) / 8; 319 320 return GL_TRUE; 321} 322 323static GLboolean 324swrast_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb, 325 GLenum internalFormat, GLuint width, GLuint height) 326{ 327 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); 328 329 TRACE; 330 331 _mesa_free(rb->Data); 332 333 swrast_alloc_front_storage(ctx, rb, internalFormat, width, height); 334 335 rb->Data = _mesa_malloc(height * xrb->pitch); 336 337 return GL_TRUE; 338} 339 340static struct swrast_renderbuffer * 341swrast_new_renderbuffer(const GLvisual *visual, GLboolean front) 342{ 343 struct swrast_renderbuffer *xrb = _mesa_calloc(sizeof *xrb); 344 GLuint pixel_format; 345 346 TRACE; 347 348 if (!xrb) 349 return NULL; 350 351 _mesa_init_renderbuffer(&xrb->Base, 0); 352 353 pixel_format = choose_pixel_format(visual); 354 355 xrb->Base.Delete = swrast_delete_renderbuffer; 356 if (front) { 357 xrb->Base.AllocStorage = swrast_alloc_front_storage; 358 swrast_set_span_funcs_front(xrb, pixel_format); 359 } 360 else { 361 xrb->Base.AllocStorage = swrast_alloc_back_storage; 362 swrast_set_span_funcs_back(xrb, pixel_format); 363 } 364 365 switch (pixel_format) { 366 case PF_A8R8G8B8: 367 xrb->Base.InternalFormat = GL_RGBA; 368 xrb->Base._BaseFormat = GL_RGBA; 369 xrb->Base.DataType = GL_UNSIGNED_BYTE; 370 xrb->Base.RedBits = 8 * sizeof(GLubyte); 371 xrb->Base.GreenBits = 8 * sizeof(GLubyte); 372 xrb->Base.BlueBits = 8 * sizeof(GLubyte); 373 xrb->Base.AlphaBits = 8 * sizeof(GLubyte); 374 xrb->bpp = 32; 375 break; 376 case PF_X8R8G8B8: 377 xrb->Base.InternalFormat = GL_RGB; 378 xrb->Base._BaseFormat = GL_RGB; 379 xrb->Base.DataType = GL_UNSIGNED_BYTE; 380 xrb->Base.RedBits = 8 * sizeof(GLubyte); 381 xrb->Base.GreenBits = 8 * sizeof(GLubyte); 382 xrb->Base.BlueBits = 8 * sizeof(GLubyte); 383 xrb->Base.AlphaBits = 0; 384 xrb->bpp = 32; 385 break; 386 case PF_R5G6B5: 387 xrb->Base.InternalFormat = GL_RGB; 388 xrb->Base._BaseFormat = GL_RGB; 389 xrb->Base.DataType = GL_UNSIGNED_BYTE; 390 xrb->Base.RedBits = 5 * sizeof(GLubyte); 391 xrb->Base.GreenBits = 6 * sizeof(GLubyte); 392 xrb->Base.BlueBits = 5 * sizeof(GLubyte); 393 xrb->Base.AlphaBits = 0; 394 xrb->bpp = 16; 395 break; 396 case PF_R3G3B2: 397 xrb->Base.InternalFormat = GL_RGB; 398 xrb->Base._BaseFormat = GL_RGB; 399 xrb->Base.DataType = GL_UNSIGNED_BYTE; 400 xrb->Base.RedBits = 3 * sizeof(GLubyte); 401 xrb->Base.GreenBits = 3 * sizeof(GLubyte); 402 xrb->Base.BlueBits = 2 * sizeof(GLubyte); 403 xrb->Base.AlphaBits = 0; 404 xrb->bpp = 8; 405 break; 406 case PF_CI8: 407 xrb->Base.InternalFormat = GL_COLOR_INDEX8_EXT; 408 xrb->Base._BaseFormat = GL_COLOR_INDEX; 409 xrb->Base.DataType = GL_UNSIGNED_BYTE; 410 xrb->Base.IndexBits = 8 * sizeof(GLubyte); 411 xrb->bpp = 8; 412 break; 413 default: 414 return NULL; 415 } 416 417 return xrb; 418} 419 420static __DRIdrawable * 421driCreateNewDrawable(__DRIscreen *screen, 422 const __DRIconfig *config, void *data) 423{ 424 __DRIdrawable *buf; 425 struct swrast_renderbuffer *frontrb, *backrb; 426 427 TRACE; 428 429 buf = _mesa_calloc(sizeof *buf); 430 if (!buf) 431 return NULL; 432 433 buf->loaderPrivate = data; 434 435 buf->driScreenPriv = screen; 436 437 buf->row = _mesa_malloc(MAX_WIDTH * 4); 438 439 /* basic framebuffer setup */ 440 _mesa_initialize_framebuffer(&buf->Base, &config->modes); 441 442 /* add front renderbuffer */ 443 frontrb = swrast_new_renderbuffer(&config->modes, GL_TRUE); 444 _mesa_add_renderbuffer(&buf->Base, BUFFER_FRONT_LEFT, &frontrb->Base); 445 446 /* add back renderbuffer */ 447 if (config->modes.doubleBufferMode) { 448 backrb = swrast_new_renderbuffer(&config->modes, GL_FALSE); 449 _mesa_add_renderbuffer(&buf->Base, BUFFER_BACK_LEFT, &backrb->Base); 450 } 451 452 /* add software renderbuffers */ 453 _mesa_add_soft_renderbuffers(&buf->Base, 454 GL_FALSE, /* color */ 455 config->modes.haveDepthBuffer, 456 config->modes.haveStencilBuffer, 457 config->modes.haveAccumBuffer, 458 GL_FALSE, /* alpha */ 459 GL_FALSE /* aux bufs */); 460 461 return buf; 462} 463 464static void 465driDestroyDrawable(__DRIdrawable *buf) 466{ 467 TRACE; 468 469 if (buf) { 470 struct gl_framebuffer *fb = &buf->Base; 471 472 _mesa_free(buf->row); 473 474 fb->DeletePending = GL_TRUE; 475 _mesa_unreference_framebuffer(&fb); 476 } 477} 478 479static void driSwapBuffers(__DRIdrawable *buf) 480{ 481 GET_CURRENT_CONTEXT(ctx); 482 483 struct swrast_renderbuffer *frontrb = 484 swrast_renderbuffer(buf->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer); 485 struct swrast_renderbuffer *backrb = 486 swrast_renderbuffer(buf->Base.Attachment[BUFFER_BACK_LEFT].Renderbuffer); 487 488 __DRIscreen *screen = buf->driScreenPriv; 489 490 TRACE; 491 492 /* check for signle-buffered */ 493 if (backrb == NULL) 494 return; 495 496 /* check if swapping currently bound buffer */ 497 if (ctx && ctx->DrawBuffer == &(buf->Base)) { 498 /* flush pending rendering */ 499 _mesa_notifySwapBuffers(ctx); 500 } 501 502 screen->swrast_loader->putImage(buf, __DRI_SWRAST_IMAGE_OP_SWAP, 503 0, 0, 504 frontrb->Base.Width, 505 frontrb->Base.Height, 506 backrb->Base.Data, 507 buf->loaderPrivate); 508} 509 510 511/** 512 * General device driver functions. 513 */ 514 515static void 516get_window_size( GLframebuffer *fb, GLsizei *w, GLsizei *h ) 517{ 518 __DRIdrawable *buf = swrast_drawable(fb); 519 __DRIscreen *screen = buf->driScreenPriv; 520 int x, y; 521 522 screen->swrast_loader->getDrawableInfo(buf, 523 &x, &y, w, h, 524 buf->loaderPrivate); 525} 526 527static void 528swrast_check_and_update_window_size( GLcontext *ctx, GLframebuffer *fb ) 529{ 530 GLsizei width, height; 531 532 get_window_size(fb, &width, &height); 533 if (fb->Width != width || fb->Height != height) { 534 _mesa_resize_framebuffer(ctx, fb, width, height); 535 } 536} 537 538static const GLubyte * 539get_string(GLcontext *ctx, GLenum pname) 540{ 541 (void) ctx; 542 switch (pname) { 543 case GL_VENDOR: 544 return (const GLubyte *) "Mesa Project"; 545 case GL_RENDERER: 546 return (const GLubyte *) "Software Rasterizer"; 547 default: 548 return NULL; 549 } 550} 551 552static void 553update_state( GLcontext *ctx, GLuint new_state ) 554{ 555 /* not much to do here - pass it on */ 556 _swrast_InvalidateState( ctx, new_state ); 557 _swsetup_InvalidateState( ctx, new_state ); 558 _vbo_InvalidateState( ctx, new_state ); 559 _tnl_InvalidateState( ctx, new_state ); 560} 561 562static void 563viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) 564{ 565 GLframebuffer *draw = ctx->WinSysDrawBuffer; 566 GLframebuffer *read = ctx->WinSysReadBuffer; 567 568 swrast_check_and_update_window_size(ctx, draw); 569 swrast_check_and_update_window_size(ctx, read); 570} 571 572static void 573swrast_init_driver_functions(struct dd_function_table *driver) 574{ 575 driver->GetString = get_string; 576 driver->UpdateState = update_state; 577 driver->GetBufferSize = NULL; 578 driver->Viewport = viewport; 579} 580 581 582/** 583 * Context-related functions. 584 */ 585 586static __DRIcontext * 587driCreateNewContext(__DRIscreen *screen, const __DRIconfig *config, 588 __DRIcontext *shared, void *data) 589{ 590 __DRIcontext *ctx; 591 GLcontext *mesaCtx; 592 struct dd_function_table functions; 593 594 TRACE; 595 596 ctx = _mesa_calloc(sizeof *ctx); 597 if (!ctx) 598 return NULL; 599 600 ctx->loaderPrivate = data; 601 602 ctx->driScreenPriv = screen; 603 604 /* build table of device driver functions */ 605 _mesa_init_driver_functions(&functions); 606 swrast_init_driver_functions(&functions); 607 608 if (!_mesa_initialize_context(&ctx->Base, &config->modes, 609 shared ? &shared->Base : NULL, 610 &functions, (void *) ctx)) { 611 _mesa_free(ctx); 612 return NULL; 613 } 614 615 mesaCtx = &ctx->Base; 616 617 /* do bounds checking to prevent segfaults and server crashes! */ 618 mesaCtx->Const.CheckArrayBounds = GL_TRUE; 619 620 /* create module contexts */ 621 _swrast_CreateContext( mesaCtx ); 622 _vbo_CreateContext( mesaCtx ); 623 _tnl_CreateContext( mesaCtx ); 624 _swsetup_CreateContext( mesaCtx ); 625 _swsetup_Wakeup( mesaCtx ); 626 627 /* use default TCL pipeline */ 628 { 629 TNLcontext *tnl = TNL_CONTEXT(mesaCtx); 630 tnl->Driver.RunPipeline = _tnl_run_pipeline; 631 } 632 633 _mesa_enable_sw_extensions(mesaCtx); 634 _mesa_enable_1_3_extensions(mesaCtx); 635 _mesa_enable_1_4_extensions(mesaCtx); 636 _mesa_enable_1_5_extensions(mesaCtx); 637 _mesa_enable_2_0_extensions(mesaCtx); 638 _mesa_enable_2_1_extensions(mesaCtx); 639 640 return ctx; 641} 642 643static void 644driDestroyContext(__DRIcontext *ctx) 645{ 646 GLcontext *mesaCtx; 647 TRACE; 648 649 if (ctx) { 650 mesaCtx = &ctx->Base; 651 _swsetup_DestroyContext( mesaCtx ); 652 _swrast_DestroyContext( mesaCtx ); 653 _tnl_DestroyContext( mesaCtx ); 654 _vbo_DestroyContext( mesaCtx ); 655 _mesa_destroy_context( mesaCtx ); 656 } 657} 658 659static int 660driCopyContext(__DRIcontext *dst, __DRIcontext *src, unsigned long mask) 661{ 662 TRACE; 663 664 _mesa_copy_context(&src->Base, &dst->Base, mask); 665 return GL_TRUE; 666} 667 668static int driBindContext(__DRIcontext *ctx, 669 __DRIdrawable *draw, 670 __DRIdrawable *read) 671{ 672 GLcontext *mesaCtx; 673 GLframebuffer *mesaDraw; 674 GLframebuffer *mesaRead; 675 TRACE; 676 677 if (ctx) { 678 if (!draw || !read) 679 return GL_FALSE; 680 681 mesaCtx = &ctx->Base; 682 mesaDraw = &draw->Base; 683 mesaRead = &read->Base; 684 685 /* check for same context and buffer */ 686 if (mesaCtx == _mesa_get_current_context() 687 && mesaCtx->DrawBuffer == mesaDraw 688 && mesaCtx->ReadBuffer == mesaRead) { 689 return GL_TRUE; 690 } 691 692 _glapi_check_multithread(); 693 694 swrast_check_and_update_window_size(mesaCtx, mesaDraw); 695 if (read != draw) 696 swrast_check_and_update_window_size(mesaCtx, mesaRead); 697 698 _mesa_make_current( mesaCtx, 699 mesaDraw, 700 mesaRead ); 701 } 702 else { 703 /* unbind */ 704 _mesa_make_current( NULL, NULL, NULL ); 705 } 706 707 return GL_TRUE; 708} 709 710static int driUnbindContext(__DRIcontext *ctx) 711{ 712 TRACE; 713 (void) ctx; 714 return GL_TRUE; 715} 716 717 718static const __DRIcoreExtension driCoreExtension = { 719 { __DRI_CORE, __DRI_CORE_VERSION }, 720 NULL, /* driCreateNewScreen */ 721 driDestroyScreen, 722 driGetExtensions, 723 driGetConfigAttrib, 724 driIndexConfigAttrib, 725 NULL, /* driCreateNewDrawable */ 726 driDestroyDrawable, 727 driSwapBuffers, 728 driCreateNewContext, 729 driCopyContext, 730 driDestroyContext, 731 driBindContext, 732 driUnbindContext 733}; 734 735static const __DRIswrastExtension driSWRastExtension = { 736 { __DRI_SWRAST, __DRI_SWRAST_VERSION }, 737 driCreateNewScreen, 738 driCreateNewDrawable 739}; 740 741/* This is the table of extensions that the loader will dlsym() for. */ 742PUBLIC const __DRIextension *__driDriverExtensions[] = { 743 &driCoreExtension.base, 744 &driSWRastExtension.base, 745 NULL 746}; 747