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