00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00055 #ifdef __CYGWIN__
00056 #undef WIN32
00057 #undef __WIN32__
00058 #endif
00059
00060 #include "glxheader.h"
00061 #include "GL/xmesa.h"
00062 #include "xmesaP.h"
00063 #include "main/context.h"
00064 #include "main/framebuffer.h"
00065
00066 #include "state_tracker/st_public.h"
00067 #include "state_tracker/st_context.h"
00068 #include "pipe/p_defines.h"
00069 #include "pipe/p_screen.h"
00070 #include "pipe/p_context.h"
00071
00072 #include "xm_winsys_aub.h"
00073
00077 pipe_mutex _xmesa_lock;
00078
00079
00080 int xmesa_mode;
00081
00082
00083
00084
00085
00086
00087
00091 #ifndef XFree86Server
00092 static int host_byte_order( void )
00093 {
00094 int i = 1;
00095 char *cptr = (char *) &i;
00096 return (*cptr==1) ? LSBFirst : MSBFirst;
00097 }
00098 #endif
00099
00100
00107 int xmesa_check_for_xshm( XMesaDisplay *display )
00108 {
00109 #if defined(USE_XSHM) && !defined(XFree86Server)
00110 int major, minor, ignore;
00111 Bool pixmaps;
00112
00113 if (getenv("SP_NO_RAST"))
00114 return 0;
00115
00116 if (getenv("MESA_NOSHM")) {
00117 return 0;
00118 }
00119
00120 if (XQueryExtension( display, "MIT-SHM", &ignore, &ignore, &ignore )) {
00121 if (XShmQueryVersion( display, &major, &minor, &pixmaps )==True) {
00122 return (pixmaps==True) ? 2 : 1;
00123 }
00124 else {
00125 return 0;
00126 }
00127 }
00128 else {
00129 return 0;
00130 }
00131 #else
00132
00133 return 0;
00134 #endif
00135 }
00136
00137
00146 static int
00147 bits_per_pixel( XMesaVisual xmv )
00148 {
00149 #ifdef XFree86Server
00150 const int depth = xmv->nplanes;
00151 int i;
00152 assert(depth > 0);
00153 for (i = 0; i < screenInfo.numPixmapFormats; i++) {
00154 if (screenInfo.formats[i].depth == depth)
00155 return screenInfo.formats[i].bitsPerPixel;
00156 }
00157 return depth;
00158 #else
00159 XMesaDisplay *dpy = xmv->display;
00160 XMesaVisualInfo visinfo = xmv->visinfo;
00161 XMesaImage *img;
00162 int bitsPerPixel;
00163
00164 img = XCreateImage( dpy, visinfo->visual, visinfo->depth,
00165 ZPixmap, 0,
00166 (char*) MALLOC(8),
00167 1, 1,
00168 32,
00169 0
00170 );
00171 assert(img);
00172
00173 bitsPerPixel = img->bits_per_pixel;
00174
00175 _mesa_free( img->data );
00176 img->data = NULL;
00177 XMesaDestroyImage( img );
00178 return bitsPerPixel;
00179 #endif
00180 }
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193 #ifndef XFree86Server
00194 static GLboolean WindowExistsFlag;
00195
00196 static int window_exists_err_handler( XMesaDisplay* dpy, XErrorEvent* xerr )
00197 {
00198 (void) dpy;
00199 if (xerr->error_code == BadWindow) {
00200 WindowExistsFlag = GL_FALSE;
00201 }
00202 return 0;
00203 }
00204
00205 static GLboolean window_exists( XMesaDisplay *dpy, Window win )
00206 {
00207 XWindowAttributes wa;
00208 int (*old_handler)( XMesaDisplay*, XErrorEvent* );
00209 WindowExistsFlag = GL_TRUE;
00210 old_handler = XSetErrorHandler(window_exists_err_handler);
00211 XGetWindowAttributes( dpy, win, &wa );
00212 XSetErrorHandler(old_handler);
00213 return WindowExistsFlag;
00214 }
00215
00216 static Status
00217 get_drawable_size( XMesaDisplay *dpy, Drawable d, uint *width, uint *height )
00218 {
00219 Window root;
00220 Status stat;
00221 int xpos, ypos;
00222 unsigned int w, h, bw, depth;
00223 stat = XGetGeometry(dpy, d, &root, &xpos, &ypos, &w, &h, &bw, &depth);
00224 *width = w;
00225 *height = h;
00226 return stat;
00227 }
00228 #endif
00229
00230
00237 static void
00238 xmesa_get_window_size(XMesaDisplay *dpy, XMesaBuffer b,
00239 GLuint *width, GLuint *height)
00240 {
00241 #ifdef XFree86Server
00242 *width = MIN2(b->drawable->width, MAX_WIDTH);
00243 *height = MIN2(b->drawable->height, MAX_HEIGHT);
00244 #else
00245 Status stat;
00246
00247 pipe_mutex_lock(_xmesa_lock);
00248 XSync(b->xm_visual->display, 0);
00249 stat = get_drawable_size(dpy, b->drawable, width, height);
00250 pipe_mutex_unlock(_xmesa_lock);
00251
00252 if (!stat) {
00253
00254 _mesa_warning(NULL, "XGetGeometry failed!\n");
00255 *width = *height = 1;
00256 }
00257 #endif
00258 }
00259
00260
00266 static GLuint
00267 choose_pixel_format(XMesaVisual v)
00268 {
00269 if ( GET_REDMASK(v) == 0x0000ff
00270 && GET_GREENMASK(v) == 0x00ff00
00271 && GET_BLUEMASK(v) == 0xff0000
00272 && v->BitsPerPixel == 32) {
00273 if (CHECK_BYTE_ORDER(v)) {
00274
00275 return 0 ;
00276 }
00277 else {
00278 return PIPE_FORMAT_R8G8B8A8_UNORM;
00279 }
00280 }
00281 else if ( GET_REDMASK(v) == 0xff0000
00282 && GET_GREENMASK(v) == 0x00ff00
00283 && GET_BLUEMASK(v) == 0x0000ff
00284 && v->BitsPerPixel == 32) {
00285 if (CHECK_BYTE_ORDER(v)) {
00286
00287 return PIPE_FORMAT_A8R8G8B8_UNORM;
00288 }
00289 else {
00290 return PIPE_FORMAT_B8G8R8A8_UNORM;
00291 }
00292 }
00293 else if ( GET_REDMASK(v) == 0xf800
00294 && GET_GREENMASK(v) == 0x07e0
00295 && GET_BLUEMASK(v) == 0x001f
00296 && CHECK_BYTE_ORDER(v)
00297 && v->BitsPerPixel == 16) {
00298
00299 return PIPE_FORMAT_R5G6B5_UNORM;
00300 }
00301
00302 assert(0);
00303 return 0;
00304 }
00305
00306
00307
00308
00309
00310
00311
00312 XMesaBuffer XMesaBufferList = NULL;
00313
00314
00326 static XMesaBuffer
00327 create_xmesa_buffer(XMesaDrawable d, BufferType type,
00328 XMesaVisual vis, XMesaColormap cmap)
00329 {
00330 XMesaBuffer b;
00331 GLframebuffer *fb;
00332 enum pipe_format colorFormat, depthFormat, stencilFormat;
00333 uint width, height;
00334
00335 ASSERT(type == WINDOW || type == PIXMAP || type == PBUFFER);
00336
00337 b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer);
00338 if (!b)
00339 return NULL;
00340
00341 b->drawable = d;
00342
00343 b->xm_visual = vis;
00344 b->type = type;
00345 b->cmap = cmap;
00346
00347
00348 colorFormat = choose_pixel_format(vis);
00349
00350 if (vis->mesa_visual.depthBits == 0)
00351 depthFormat = PIPE_FORMAT_NONE;
00352 #ifdef GALLIUM_CELL
00353 else
00354 depthFormat = PIPE_FORMAT_S8Z24_UNORM;
00355 #else
00356 else if (vis->mesa_visual.depthBits <= 16)
00357 depthFormat = PIPE_FORMAT_Z16_UNORM;
00358 else if (vis->mesa_visual.depthBits <= 24)
00359 depthFormat = PIPE_FORMAT_S8Z24_UNORM;
00360 else
00361 depthFormat = PIPE_FORMAT_Z32_UNORM;
00362 #endif
00363
00364 if (vis->mesa_visual.stencilBits == 8) {
00365 if (depthFormat == PIPE_FORMAT_S8Z24_UNORM)
00366 stencilFormat = depthFormat;
00367 else
00368 stencilFormat = PIPE_FORMAT_S8_UNORM;
00369 }
00370 else {
00371
00372 stencilFormat = PIPE_FORMAT_NONE;
00373 if (depthFormat == PIPE_FORMAT_S8Z24_UNORM) {
00374
00375 depthFormat = PIPE_FORMAT_X8Z24_UNORM;
00376 }
00377 }
00378
00379
00380 get_drawable_size(vis->display, d, &width, &height);
00381
00382
00383
00384
00385 b->stfb = st_create_framebuffer(&vis->mesa_visual,
00386 colorFormat, depthFormat, stencilFormat,
00387 width, height,
00388 (void *) b);
00389 fb = &b->stfb->Base;
00390
00391
00392
00393
00394 b->tempImage = XCreateImage(vis->display,
00395 vis->visinfo->visual,
00396 vis->visinfo->depth,
00397 ZPixmap, 0,
00398 NULL,
00399 0, 0,
00400 32,
00401 0);
00402
00403
00404 b->TextureTarget = 0;
00405 b->TextureFormat = GLX_TEXTURE_FORMAT_NONE_EXT;
00406 b->TextureMipmap = 0;
00407
00408
00409 b->Next = XMesaBufferList;
00410 XMesaBufferList = b;
00411
00412 return b;
00413 }
00414
00415
00420 XMesaBuffer
00421 xmesa_find_buffer(XMesaDisplay *dpy, XMesaColormap cmap, XMesaBuffer notThis)
00422 {
00423 XMesaBuffer b;
00424 for (b = XMesaBufferList; b; b = b->Next) {
00425 if (b->xm_visual->display == dpy &&
00426 b->cmap == cmap &&
00427 b != notThis) {
00428 return b;
00429 }
00430 }
00431 return NULL;
00432 }
00433
00434
00438 static void
00439 xmesa_free_buffer(XMesaBuffer buffer)
00440 {
00441 XMesaBuffer prev = NULL, b;
00442
00443 for (b = XMesaBufferList; b; b = b->Next) {
00444 if (b == buffer) {
00445 struct gl_framebuffer *fb = &buffer->stfb->Base;
00446
00447
00448 if (prev)
00449 prev->Next = buffer->Next;
00450 else
00451 XMesaBufferList = buffer->Next;
00452
00453
00454 fb->DeletePending = GL_TRUE;
00455
00456
00457
00458
00459 b->drawable = 0;
00460
00461 buffer->tempImage->data = NULL;
00462 XDestroyImage(buffer->tempImage);
00463
00464
00465 _mesa_unreference_framebuffer(&fb);
00466
00467 XFreeGC(b->xm_visual->display, b->gc);
00468
00469 free(buffer);
00470
00471 return;
00472 }
00473
00474 prev = b;
00475 }
00476
00477 _mesa_problem(NULL,"xmesa_free_buffer() - buffer not found\n");
00478 }
00479
00480
00481
00482
00483
00484
00485
00486
00497 static GLboolean
00498 initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b,
00499 GLboolean rgb_flag, XMesaDrawable window,
00500 XMesaColormap cmap)
00501 {
00502 #ifdef XFree86Server
00503 int client = (window) ? CLIENT_ID(window->id) : 0;
00504 #endif
00505
00506 ASSERT(!b || b->xm_visual == v);
00507
00508
00509 v->BitsPerPixel = bits_per_pixel(v);
00510 assert(v->BitsPerPixel > 0);
00511
00512 if (rgb_flag == GL_FALSE) {
00513
00514 return GL_FALSE;
00515 }
00516 else {
00517
00518
00519
00520 const int xclass = v->mesa_visual.visualType;
00521 if (xclass != GLX_TRUE_COLOR && xclass == !GLX_DIRECT_COLOR) {
00522 _mesa_warning(NULL,
00523 "XMesa: RGB mode rendering not supported in given visual.\n");
00524 return GL_FALSE;
00525 }
00526 v->mesa_visual.indexBits = 0;
00527
00528 if (v->BitsPerPixel == 32) {
00529
00530
00531
00532
00533 v->mesa_visual.alphaBits = 8;
00534 }
00535 }
00536
00537
00538
00539
00540
00541
00542 if (_mesa_getenv("MESA_INFO")) {
00543 _mesa_printf("X/Mesa visual = %p\n", (void *) v);
00544 _mesa_printf("X/Mesa level = %d\n", v->mesa_visual.level);
00545 _mesa_printf("X/Mesa depth = %d\n", GET_VISUAL_DEPTH(v));
00546 _mesa_printf("X/Mesa bits per pixel = %d\n", v->BitsPerPixel);
00547 }
00548
00549 if (b && window) {
00550
00551 ASSERT(b->drawable == window);
00552
00553
00554 if (v->mesa_visual.doubleBufferMode) {
00555
00556 b->shm = xmesa_check_for_xshm( v->display );
00557 }
00558
00559
00560 #ifdef XFree86Server
00561 b->gc = CreateScratchGC(v->display, window->depth);
00562 #else
00563 b->gc = XCreateGC( v->display, window, 0, NULL );
00564 #endif
00565 XMesaSetFunction( v->display, b->gc, GXcopy );
00566 }
00567
00568 return GL_TRUE;
00569 }
00570
00571
00572
00573 #define NUM_VISUAL_TYPES 6
00574
00587 static GLint
00588 xmesa_convert_from_x_visual_type( int visualType )
00589 {
00590 static const int glx_visual_types[ NUM_VISUAL_TYPES ] = {
00591 GLX_STATIC_GRAY, GLX_GRAY_SCALE,
00592 GLX_STATIC_COLOR, GLX_PSEUDO_COLOR,
00593 GLX_TRUE_COLOR, GLX_DIRECT_COLOR
00594 };
00595
00596 return ( (unsigned) visualType < NUM_VISUAL_TYPES )
00597 ? glx_visual_types[ visualType ] : GLX_NONE;
00598 }
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629 PUBLIC
00630 XMesaVisual XMesaCreateVisual( XMesaDisplay *display,
00631 XMesaVisualInfo visinfo,
00632 GLboolean rgb_flag,
00633 GLboolean alpha_flag,
00634 GLboolean db_flag,
00635 GLboolean stereo_flag,
00636 GLboolean ximage_flag,
00637 GLint depth_size,
00638 GLint stencil_size,
00639 GLint accum_red_size,
00640 GLint accum_green_size,
00641 GLint accum_blue_size,
00642 GLint accum_alpha_size,
00643 GLint num_samples,
00644 GLint level,
00645 GLint visualCaveat )
00646 {
00647 XMesaVisual v;
00648 GLint red_bits, green_bits, blue_bits, alpha_bits;
00649
00650 #ifndef XFree86Server
00651
00652 if (_mesa_getenv("MESA_XSYNC")) {
00653
00654
00655
00656
00657 XSynchronize( display, 1 );
00658 }
00659 #endif
00660
00661 v = (XMesaVisual) CALLOC_STRUCT(xmesa_visual);
00662 if (!v) {
00663 return NULL;
00664 }
00665
00666 v->display = display;
00667
00668
00669
00670
00671
00672 #ifndef XFree86Server
00673 v->visinfo = (XVisualInfo *) MALLOC(sizeof(*visinfo));
00674 if(!v->visinfo) {
00675 _mesa_free(v);
00676 return NULL;
00677 }
00678 MEMCPY(v->visinfo, visinfo, sizeof(*visinfo));
00679 #endif
00680
00681 v->ximage_flag = ximage_flag;
00682
00683 #ifdef XFree86Server
00684
00685
00686
00687
00688
00689 assert(visinfo->nplanes > 0);
00690 v->nplanes = visinfo->nplanes;
00691 v->ColormapEntries = visinfo->ColormapEntries;
00692
00693 v->mesa_visual.redMask = visinfo->redMask;
00694 v->mesa_visual.greenMask = visinfo->greenMask;
00695 v->mesa_visual.blueMask = visinfo->blueMask;
00696 v->mesa_visual.visualID = visinfo->vid;
00697 v->mesa_visual.screen = 0;
00698 #else
00699 v->mesa_visual.redMask = visinfo->red_mask;
00700 v->mesa_visual.greenMask = visinfo->green_mask;
00701 v->mesa_visual.blueMask = visinfo->blue_mask;
00702 v->mesa_visual.visualID = visinfo->visualid;
00703 v->mesa_visual.screen = visinfo->screen;
00704 #endif
00705
00706 #if defined(XFree86Server) || !(defined(__cplusplus) || defined(c_plusplus))
00707 v->mesa_visual.visualType = xmesa_convert_from_x_visual_type(visinfo->class);
00708 #else
00709 v->mesa_visual.visualType = xmesa_convert_from_x_visual_type(visinfo->c_class);
00710 #endif
00711
00712 v->mesa_visual.visualRating = visualCaveat;
00713
00714 if (alpha_flag)
00715 v->mesa_visual.alphaBits = 8;
00716
00717 (void) initialize_visual_and_buffer( v, NULL, rgb_flag, 0, 0 );
00718
00719 {
00720 const int xclass = v->mesa_visual.visualType;
00721 if (xclass == GLX_TRUE_COLOR || xclass == GLX_DIRECT_COLOR) {
00722 red_bits = _mesa_bitcount(GET_REDMASK(v));
00723 green_bits = _mesa_bitcount(GET_GREENMASK(v));
00724 blue_bits = _mesa_bitcount(GET_BLUEMASK(v));
00725 }
00726 else {
00727
00728 int depth;
00729 depth = GET_VISUAL_DEPTH(v);
00730 red_bits = depth / 3;
00731 depth -= red_bits;
00732 green_bits = depth / 2;
00733 depth -= green_bits;
00734 blue_bits = depth;
00735 alpha_bits = 0;
00736 assert( red_bits + green_bits + blue_bits == GET_VISUAL_DEPTH(v) );
00737 }
00738 alpha_bits = v->mesa_visual.alphaBits;
00739 }
00740
00741 _mesa_initialize_visual( &v->mesa_visual,
00742 rgb_flag, db_flag, stereo_flag,
00743 red_bits, green_bits,
00744 blue_bits, alpha_bits,
00745 v->mesa_visual.indexBits,
00746 depth_size,
00747 stencil_size,
00748 accum_red_size, accum_green_size,
00749 accum_blue_size, accum_alpha_size,
00750 0 );
00751
00752
00753 v->mesa_visual.level = level;
00754 return v;
00755 }
00756
00757
00758 PUBLIC
00759 void XMesaDestroyVisual( XMesaVisual v )
00760 {
00761 #ifndef XFree86Server
00762 _mesa_free(v->visinfo);
00763 #endif
00764 _mesa_free(v);
00765 }
00766
00767
00768
00776 PUBLIC
00777 XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
00778 {
00779 static GLboolean firstTime = GL_TRUE;
00780 struct pipe_context *pipe;
00781 XMesaContext c;
00782 GLcontext *mesaCtx;
00783 uint pf;
00784
00785 if (firstTime) {
00786 pipe_mutex_init(_xmesa_lock);
00787 firstTime = GL_FALSE;
00788 }
00789
00790
00791 c = (XMesaContext) CALLOC_STRUCT(xmesa_context);
00792 if (!c)
00793 return NULL;
00794
00795 pf = choose_pixel_format(v);
00796 assert(pf);
00797
00798 c->xm_visual = v;
00799 c->xm_buffer = NULL;
00800
00801 if (!getenv("XM_AUB")) {
00802 xmesa_mode = XMESA_SOFTPIPE;
00803 pipe = xmesa_create_pipe_context( c, pf );
00804 }
00805 else {
00806 xmesa_mode = XMESA_AUB;
00807 pipe = xmesa_create_i965simple(xmesa_get_pipe_winsys_aub(v));
00808 }
00809
00810 if (pipe == NULL)
00811 goto fail;
00812
00813 c->st = st_create_context(pipe, &v->mesa_visual,
00814 share_list ? share_list->st : NULL);
00815 if (c->st == NULL)
00816 goto fail;
00817
00818 mesaCtx = c->st->ctx;
00819 c->st->ctx->DriverCtx = c;
00820
00821 #if 00
00822 _mesa_enable_sw_extensions(mesaCtx);
00823 _mesa_enable_1_3_extensions(mesaCtx);
00824 _mesa_enable_1_4_extensions(mesaCtx);
00825 _mesa_enable_1_5_extensions(mesaCtx);
00826 _mesa_enable_2_0_extensions(mesaCtx);
00827 #endif
00828
00829 #ifdef XFree86Server
00830
00831
00832
00833 mesaCtx->Const.CheckArrayBounds = GL_TRUE;
00834 #endif
00835
00836 return c;
00837
00838 fail:
00839 if (c->st)
00840 st_destroy_context(c->st);
00841 else if (pipe)
00842 pipe->destroy(pipe);
00843 FREE(c);
00844 return NULL;
00845 }
00846
00847
00848
00849 PUBLIC
00850 void XMesaDestroyContext( XMesaContext c )
00851 {
00852 struct pipe_screen *screen = c->st->pipe->screen;
00853 st_destroy_context(c->st);
00854
00855
00856
00857
00858 _mesa_free(c);
00859 }
00860
00861
00862
00870 PUBLIC XMesaBuffer
00871 XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w)
00872 {
00873 #ifndef XFree86Server
00874 XWindowAttributes attr;
00875 #endif
00876 XMesaBuffer b;
00877 XMesaColormap cmap;
00878 int depth;
00879
00880 assert(v);
00881 assert(w);
00882
00883
00884 #ifdef XFree86Server
00885 depth = ((XMesaDrawable)w)->depth;
00886 #else
00887 XGetWindowAttributes( v->display, w, &attr );
00888 depth = attr.depth;
00889 #endif
00890 if (GET_VISUAL_DEPTH(v) != depth) {
00891 _mesa_warning(NULL, "XMesaCreateWindowBuffer: depth mismatch between visual (%d) and window (%d)!\n",
00892 GET_VISUAL_DEPTH(v), depth);
00893 return NULL;
00894 }
00895
00896
00897 #ifdef XFree86Server
00898 cmap = (ColormapPtr)LookupIDByType(wColormap(w), RT_COLORMAP);
00899 #else
00900 if (attr.colormap) {
00901 cmap = attr.colormap;
00902 }
00903 else {
00904 _mesa_warning(NULL, "Window %u has no colormap!\n", (unsigned int) w);
00905
00906
00907 cmap = XCreateColormap(v->display, w, attr.visual, AllocNone);
00908 }
00909 #endif
00910
00911 b = create_xmesa_buffer((XMesaDrawable) w, WINDOW, v, cmap);
00912 if (!b)
00913 return NULL;
00914
00915 if (!initialize_visual_and_buffer( v, b, v->mesa_visual.rgbMode,
00916 (XMesaDrawable) w, cmap )) {
00917 xmesa_free_buffer(b);
00918 return NULL;
00919 }
00920
00921 return b;
00922 }
00923
00924
00925
00935 PUBLIC XMesaBuffer
00936 XMesaCreatePixmapBuffer(XMesaVisual v, XMesaPixmap p, XMesaColormap cmap)
00937 {
00938 XMesaBuffer b;
00939
00940 assert(v);
00941
00942 b = create_xmesa_buffer((XMesaDrawable) p, PIXMAP, v, cmap);
00943 if (!b)
00944 return NULL;
00945
00946 if (!initialize_visual_and_buffer(v, b, v->mesa_visual.rgbMode,
00947 (XMesaDrawable) p, cmap)) {
00948 xmesa_free_buffer(b);
00949 return NULL;
00950 }
00951
00952 return b;
00953 }
00954
00955
00959 XMesaBuffer
00960 XMesaCreatePixmapTextureBuffer(XMesaVisual v, XMesaPixmap p,
00961 XMesaColormap cmap,
00962 int format, int target, int mipmap)
00963 {
00964 GET_CURRENT_CONTEXT(ctx);
00965 XMesaBuffer b;
00966 GLuint width, height;
00967
00968 assert(v);
00969
00970 b = create_xmesa_buffer((XMesaDrawable) p, PIXMAP, v, cmap);
00971 if (!b)
00972 return NULL;
00973
00974
00975 xmesa_get_window_size(v->display, b, &width, &height);
00976 _mesa_resize_framebuffer(NULL, &(b->stfb->Base), width, height);
00977
00978 if (target == 0) {
00979
00980 if (ctx->Extensions.ARB_texture_non_power_of_two) {
00981 target = GLX_TEXTURE_2D_EXT;
00982 }
00983 else if ( _mesa_bitcount(width) == 1
00984 && _mesa_bitcount(height) == 1) {
00985
00986 if (height == 1) {
00987 target = GLX_TEXTURE_1D_EXT;
00988 }
00989 else {
00990 target = GLX_TEXTURE_2D_EXT;
00991 }
00992 }
00993 else if (ctx->Extensions.NV_texture_rectangle) {
00994 target = GLX_TEXTURE_RECTANGLE_EXT;
00995 }
00996 else {
00997
00998 XMesaDestroyBuffer(b);
00999 return 0;
01000 }
01001 }
01002
01003 b->TextureTarget = target;
01004 b->TextureFormat = format;
01005 b->TextureMipmap = mipmap;
01006
01007 if (!initialize_visual_and_buffer(v, b, v->mesa_visual.rgbMode,
01008 (XMesaDrawable) p, cmap)) {
01009 xmesa_free_buffer(b);
01010 return NULL;
01011 }
01012
01013 return b;
01014 }
01015
01016
01017
01018 XMesaBuffer
01019 XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap,
01020 unsigned int width, unsigned int height)
01021 {
01022 #ifndef XFree86Server
01023 XMesaWindow root;
01024 XMesaDrawable drawable;
01025 XMesaBuffer b;
01026
01027
01028 root = RootWindow( v->display, v->visinfo->screen );
01029 drawable = XCreatePixmap(v->display, root, width, height,
01030 v->visinfo->depth);
01031 if (!drawable)
01032 return NULL;
01033
01034 b = create_xmesa_buffer(drawable, PBUFFER, v, cmap);
01035 if (!b)
01036 return NULL;
01037
01038 if (!initialize_visual_and_buffer(v, b, v->mesa_visual.rgbMode,
01039 drawable, cmap)) {
01040 xmesa_free_buffer(b);
01041 return NULL;
01042 }
01043
01044 return b;
01045 #else
01046 return 0;
01047 #endif
01048 }
01049
01050
01051
01052
01053
01054
01055 PUBLIC void
01056 XMesaDestroyBuffer(XMesaBuffer b)
01057 {
01058 xmesa_free_buffer(b);
01059 }
01060
01061
01072 void
01073 xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer)
01074 {
01075 GLuint width, height;
01076 xmesa_get_window_size(drawBuffer->xm_visual->display, drawBuffer, &width, &height);
01077 st_resize_framebuffer(drawBuffer->stfb, width, height);
01078 }
01079
01080
01081
01082
01083
01084 GLboolean XMesaMakeCurrent( XMesaContext c, XMesaBuffer b )
01085 {
01086 return XMesaMakeCurrent2( c, b, b );
01087 }
01088
01089
01090
01091
01092
01093 PUBLIC
01094 GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer,
01095 XMesaBuffer readBuffer )
01096 {
01097 if (c) {
01098 if (!drawBuffer || !readBuffer)
01099 return GL_FALSE;
01100
01101 #if 0
01102
01103 if (&(c->mesa) == _mesa_get_current_context()
01104 && c->mesa.DrawBuffer == &drawBuffer->mesa_buffer
01105 && c->mesa.ReadBuffer == &readBuffer->mesa_buffer
01106 && xmesa_buffer(c->mesa.DrawBuffer)->wasCurrent) {
01107
01108 return GL_TRUE;
01109 }
01110 #endif
01111
01112 c->xm_buffer = drawBuffer;
01113
01114
01115
01116
01117 _glapi_check_multithread();
01118
01119 st_make_current(c->st, drawBuffer->stfb, readBuffer->stfb);
01120
01121 xmesa_check_and_update_buffer_size(c, drawBuffer);
01122 if (readBuffer != drawBuffer)
01123 xmesa_check_and_update_buffer_size(c, readBuffer);
01124
01125
01126 drawBuffer->wasCurrent = GL_TRUE;
01127 }
01128 else {
01129
01130 st_make_current( NULL, NULL, NULL );
01131 }
01132 return GL_TRUE;
01133 }
01134
01135
01136
01137
01138
01139 GLboolean XMesaUnbindContext( XMesaContext c )
01140 {
01141
01142 return GL_TRUE;
01143 }
01144
01145
01146 XMesaContext XMesaGetCurrentContext( void )
01147 {
01148 GET_CURRENT_CONTEXT(ctx);
01149 if (ctx) {
01150 XMesaContext xmesa = xmesa_context(ctx);
01151 return xmesa;
01152 }
01153 else {
01154 return 0;
01155 }
01156 }
01157
01158
01159 XMesaBuffer XMesaGetCurrentBuffer( void )
01160 {
01161 GET_CURRENT_CONTEXT(ctx);
01162 if (ctx) {
01163 XMesaBuffer xmbuf = xmesa_buffer(ctx->DrawBuffer);
01164 return xmbuf;
01165 }
01166 else {
01167 return 0;
01168 }
01169 }
01170
01171
01172
01173 XMesaBuffer XMesaGetCurrentReadBuffer( void )
01174 {
01175 GET_CURRENT_CONTEXT(ctx);
01176 if (ctx) {
01177 return xmesa_buffer(ctx->ReadBuffer);
01178 }
01179 else {
01180 return 0;
01181 }
01182 }
01183
01184
01185 #ifdef XFree86Server
01186 PUBLIC
01187 GLboolean XMesaForceCurrent(XMesaContext c)
01188 {
01189 if (c) {
01190 _glapi_set_dispatch(c->mesa.CurrentDispatch);
01191
01192 if (&(c->mesa) != _mesa_get_current_context()) {
01193 _mesa_make_current(&c->mesa, c->mesa.DrawBuffer, c->mesa.ReadBuffer);
01194 }
01195 }
01196 else {
01197 _mesa_make_current(NULL, NULL, NULL);
01198 }
01199 return GL_TRUE;
01200 }
01201
01202
01203 PUBLIC
01204 GLboolean XMesaLoseCurrent(XMesaContext c)
01205 {
01206 (void) c;
01207 _mesa_make_current(NULL, NULL, NULL);
01208 return GL_TRUE;
01209 }
01210
01211
01212 PUBLIC
01213 GLboolean XMesaCopyContext( XMesaContext xm_src, XMesaContext xm_dst, GLuint mask )
01214 {
01215 _mesa_copy_context(&xm_src->mesa, &xm_dst->mesa, mask);
01216 return GL_TRUE;
01217 }
01218 #endif
01219
01220
01221 #ifndef FX
01222 GLboolean XMesaSetFXmode( GLint mode )
01223 {
01224 (void) mode;
01225 return GL_FALSE;
01226 }
01227 #endif
01228
01229
01230
01231
01232
01233
01234
01235 PUBLIC
01236 void XMesaSwapBuffers( XMesaBuffer b )
01237 {
01238 struct pipe_surface *surf;
01239
01240
01241
01242
01243 st_notify_swapbuffers(b->stfb);
01244
01245 surf = st_get_framebuffer_surface(b->stfb, ST_SURFACE_BACK_LEFT);
01246 if (surf) {
01247 if (xmesa_mode == XMESA_AUB)
01248 xmesa_display_aub( surf );
01249 else
01250 xmesa_display_surface(b, surf);
01251 }
01252
01253 xmesa_check_and_update_buffer_size(NULL, b);
01254 }
01255
01256
01257
01258
01259
01260
01261 void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height )
01262 {
01263 struct pipe_surface *surf_front
01264 = st_get_framebuffer_surface(b->stfb, ST_SURFACE_FRONT_LEFT);
01265 struct pipe_surface *surf_back
01266 = st_get_framebuffer_surface(b->stfb, ST_SURFACE_BACK_LEFT);
01267 struct pipe_context *pipe = NULL;
01268
01269 if (!surf_front || !surf_back)
01270 return;
01271
01272 pipe->surface_copy(pipe,
01273 FALSE,
01274 surf_front, x, y,
01275 surf_back, x, y,
01276 width, height);
01277 }
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289 GLboolean XMesaGetDepthBuffer( XMesaBuffer b, GLint *width, GLint *height,
01290 GLint *bytesPerValue, void **buffer )
01291 {
01292 *width = 0;
01293 *height = 0;
01294 *bytesPerValue = 0;
01295 *buffer = 0;
01296 return GL_FALSE;
01297 }
01298
01299
01300 void XMesaFlush( XMesaContext c )
01301 {
01302 if (c && c->xm_visual->display) {
01303 #ifdef XFree86Server
01304
01305 #else
01306 st_finish(c->st);
01307 XSync( c->xm_visual->display, False );
01308 #endif
01309 }
01310 }
01311
01312
01313
01314 const char *XMesaGetString( XMesaContext c, int name )
01315 {
01316 (void) c;
01317 if (name==XMESA_VERSION) {
01318 return "5.0";
01319 }
01320 else if (name==XMESA_EXTENSIONS) {
01321 return "";
01322 }
01323 else {
01324 return NULL;
01325 }
01326 }
01327
01328
01329
01330 XMesaBuffer XMesaFindBuffer( XMesaDisplay *dpy, XMesaDrawable d )
01331 {
01332 XMesaBuffer b;
01333 for (b=XMesaBufferList; b; b=b->Next) {
01334 if (b->drawable == d && b->xm_visual->display == dpy) {
01335 return b;
01336 }
01337 }
01338 return NULL;
01339 }
01340
01341
01345 void xmesa_destroy_buffers_on_display(XMesaDisplay *dpy)
01346 {
01347 XMesaBuffer b, next;
01348 for (b = XMesaBufferList; b; b = next) {
01349 next = b->Next;
01350 if (b->xm_visual->display == dpy) {
01351 xmesa_free_buffer(b);
01352 }
01353 }
01354 }
01355
01356
01357
01358
01359
01360
01361 void XMesaGarbageCollect( void )
01362 {
01363 XMesaBuffer b, next;
01364 for (b=XMesaBufferList; b; b=next) {
01365 next = b->Next;
01366 if (b->xm_visual &&
01367 b->xm_visual->display &&
01368 b->drawable &&
01369 b->type == WINDOW) {
01370 #ifdef XFree86Server
01371
01372 #else
01373 XSync(b->xm_visual->display, False);
01374 if (!window_exists( b->xm_visual->display, b->drawable )) {
01375
01376 XMesaDestroyBuffer( b );
01377 }
01378 #endif
01379 }
01380 }
01381 }
01382
01383
01384 unsigned long XMesaDitherColor( XMesaContext xmesa, GLint x, GLint y,
01385 GLfloat red, GLfloat green,
01386 GLfloat blue, GLfloat alpha )
01387 {
01388
01389 return 0;
01390 }
01391
01392
01393
01394
01395
01396
01397 PUBLIC void
01398 XMesaResizeBuffers( XMesaBuffer b )
01399 {
01400 GET_CURRENT_CONTEXT(ctx);
01401 XMesaContext xmctx = xmesa_context(ctx);
01402 if (!xmctx)
01403 return;
01404 xmesa_check_and_update_buffer_size(xmctx, b);
01405 }
01406
01407
01408
01409
01410 PUBLIC void
01411 XMesaBindTexImage(XMesaDisplay *dpy, XMesaBuffer drawable, int buffer,
01412 const int *attrib_list)
01413 {
01414 }
01415
01416
01417
01418 PUBLIC void
01419 XMesaReleaseTexImage(XMesaDisplay *dpy, XMesaBuffer drawable, int buffer)
01420 {
01421 }
01422