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