Clone of mesa.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

jkrahntest.c 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /* $Id: jkrahntest.c,v 1.1 2002/06/16 03:57:48 brianp Exp $ */
  2. /* This is a good test for glXSwapBuffers on non-current windows,
  3. * and the glXCopyContext function. Fixed several Mesa/DRI bugs with
  4. * this program on 15 June 2002.
  5. *
  6. * Joe's comments follow:
  7. *
  8. * I have tried some different approaches for being able to
  9. * draw to multiple windows using one context, or a copied
  10. * context. Mesa/indirect rendering works to use one context
  11. * for multiple windows, but crashes with glXCopyContext.
  12. * DRI is badly broken, at least for ATI.
  13. *
  14. * I also noticed that glXMakeCurrent allows a window and context
  15. * from different visuals to be attached (haven't tested recently).
  16. *
  17. * Joe Krahn <jkrahn@nc.rr.com>
  18. */
  19. #include <GL/glx.h>
  20. #include <GL/gl.h>
  21. #include <string.h>
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <unistd.h>
  25. #include <math.h>
  26. #define M_PI 3.14159
  27. #define DEGTOR (M_PI/180.0)
  28. static int AttributeList[] = { GLX_RGBA, GLX_DOUBLEBUFFER, None };
  29. int main(int argc, char **argv)
  30. {
  31. Window win1, win2;
  32. XVisualInfo *vi;
  33. XSetWindowAttributes swa;
  34. Display *dpy;
  35. GLXContext ctx1, ctx2;
  36. float angle;
  37. int test;
  38. if (argc < 2) {
  39. fprintf(stderr, "This program tests GLX context switching.\n");
  40. fprintf(stderr, "Usage: cxbug <n>\n");
  41. fprintf(stderr, "Where n is:\n");
  42. fprintf(stderr, "\t1) Use two contexts and swap only when the context is current (typical case).\n");
  43. fprintf(stderr, "\t2) Use two contexts and swap at the same time.\n");
  44. fprintf(stderr, "\t\t Used to crash Mesa & nVidia, and DRI artifacts. Seems OK now.\n");
  45. fprintf(stderr, "\t3) Use one context, but only swap when a context is current.\n");
  46. fprintf(stderr, "\t\t Serious artifacts for DRI at least with ATI.\n");
  47. fprintf(stderr, "\t4) Use one context, swap both windows at the same time, so the left\n");
  48. fprintf(stderr, "\t\t window has no context at swap time. Severe artifacts for DRI.\n");
  49. fprintf(stderr, "\t5) Use two contexts, copying one to the other when switching windows.\n");
  50. fprintf(stderr, "\t\t DRI gives an error, indirect rendering crashes server.\n");
  51. exit(1);
  52. }
  53. test = atoi(argv[1]);
  54. /* get a connection */
  55. dpy = XOpenDisplay(NULL);
  56. /* Get an appropriate visual */
  57. vi = glXChooseVisual(dpy, DefaultScreen(dpy), AttributeList);
  58. if (vi == 0) {
  59. fprintf(stderr, "No matching visuals found.\n");
  60. exit(-1);
  61. }
  62. /* Create two GLX contexts, with list sharing */
  63. ctx1 = glXCreateContext(dpy, vi, 0, True);
  64. ctx2 = glXCreateContext(dpy, vi, ctx1, True);
  65. /* create a colormap */
  66. swa.colormap = XCreateColormap(dpy, RootWindow(dpy, vi->screen),
  67. vi->visual, AllocNone);
  68. swa.border_pixel = 0;
  69. /* Create two windows */
  70. win1 = XCreateWindow(dpy, RootWindow(dpy, vi->screen),
  71. 10, 10, 200, 200,
  72. 0, vi->depth, InputOutput, vi->visual,
  73. CWBorderPixel | CWColormap, &swa);
  74. XStoreName(dpy, win1, "Test [L]");
  75. XMapWindow(dpy, win1);
  76. XMoveWindow(dpy, win1, 10, 10); /* Initial requested x,y may not be honored */
  77. {
  78. XSizeHints sizehints;
  79. static const char *name = "window";
  80. sizehints.x = 10;
  81. sizehints.y = 10;
  82. sizehints.width = 200;
  83. sizehints.height = 200;
  84. sizehints.flags = USSize | USPosition;
  85. XSetNormalHints(dpy, win1, &sizehints);
  86. XSetStandardProperties(dpy, win1, name, name,
  87. None, (char **)NULL, 0, &sizehints);
  88. }
  89. win2 = XCreateWindow(dpy, RootWindow(dpy, vi->screen),
  90. 250, 10, 200, 200,
  91. 0, vi->depth, InputOutput, vi->visual,
  92. CWBorderPixel | CWColormap, &swa);
  93. XStoreName(dpy, win1, "Test [R]");
  94. XMapWindow(dpy, win2);
  95. XMoveWindow(dpy, win2, 260, 10);
  96. {
  97. XSizeHints sizehints;
  98. static const char *name = "window";
  99. sizehints.x = 10;
  100. sizehints.y = 10;
  101. sizehints.width = 200;
  102. sizehints.height = 200;
  103. sizehints.flags = USSize | USPosition;
  104. XSetNormalHints(dpy, win2, &sizehints);
  105. XSetStandardProperties(dpy, win2, name, name,
  106. None, (char **)NULL, 0, &sizehints);
  107. }
  108. /* Now draw some spinning things */
  109. for (angle = 0; angle < 360*4; angle += 10.0) {
  110. /* Connect the context to window 1 */
  111. glXMakeCurrent(dpy, win1, ctx1);
  112. /* Clear and draw in window 1 */
  113. glDrawBuffer(GL_BACK);
  114. glClearColor(1, 1, 0, 1);
  115. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  116. glColor3f(1, 0, 0);
  117. glBegin(GL_TRIANGLES);
  118. glVertex2f(0, 0);
  119. glVertex2f(cos(angle * DEGTOR), sin(angle * DEGTOR));
  120. glVertex2f(cos((angle + 20.0) * DEGTOR),
  121. sin((angle + 20.0) * DEGTOR));
  122. glEnd();
  123. glFlush();
  124. if (test == 1 || test == 3 || test == 5)
  125. glXSwapBuffers(dpy, win1);
  126. if (test == 5)
  127. glXCopyContext(dpy, ctx1, ctx2, GL_ALL_ATTRIB_BITS);
  128. /* Connect the context to window 2 */
  129. if (test == 3 || test == 4) {
  130. glXMakeCurrent(dpy, win2, ctx1);
  131. } else {
  132. glXMakeCurrent(dpy, win2, ctx2);
  133. }
  134. /* Clear and draw in window 2 */
  135. glDrawBuffer(GL_BACK);
  136. glClearColor(0, 0, 1, 1);
  137. glClear(GL_COLOR_BUFFER_BIT);
  138. glColor3f(1, 1, 0);
  139. glBegin(GL_TRIANGLES);
  140. glVertex2f(0, 0);
  141. glVertex2f(cos(angle * DEGTOR), sin(angle * DEGTOR));
  142. glVertex2f(cos((angle + 20.0) * DEGTOR),
  143. sin((angle + 20.0) * DEGTOR));
  144. glEnd();
  145. glFlush();
  146. /* Swap buffers */
  147. if (test == 2 || test == 4)
  148. glXSwapBuffers(dpy, win1);
  149. glXSwapBuffers(dpy, win2);
  150. /* wait a while */
  151. glXWaitX();
  152. usleep(20000);
  153. }
  154. return 0;
  155. }