single2swap.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. /*
  2. * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
  3. * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a
  6. * copy of this software and associated documentation files (the "Software"),
  7. * to deal in the Software without restriction, including without limitation
  8. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9. * and/or sell copies of the Software, and to permit persons to whom the
  10. * Software is furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice including the dates of first publication and
  13. * either this permission notice or a reference to
  14. * http://oss.sgi.com/projects/FreeB/
  15. * shall be included in all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20. * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  21. * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
  22. * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23. * SOFTWARE.
  24. *
  25. * Except as contained in this notice, the name of Silicon Graphics, Inc.
  26. * shall not be used in advertising or otherwise to promote the sale, use or
  27. * other dealings in this Software without prior written authorization from
  28. * Silicon Graphics, Inc.
  29. */
  30. #ifdef HAVE_DIX_CONFIG_H
  31. #include <dix-config.h>
  32. #endif
  33. #include "glxserver.h"
  34. #include "glxutil.h"
  35. #include "glxext.h"
  36. #include "indirect_dispatch.h"
  37. #include "unpack.h"
  38. int
  39. __glXDispSwap_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc)
  40. {
  41. ClientPtr client = cl->client;
  42. GLsizei size;
  43. GLenum type;
  44. __GLX_DECLARE_SWAP_VARIABLES;
  45. __GLXcontext *cx;
  46. int error;
  47. REQUEST_FIXED_SIZE(xGLXSingleReq, 8);
  48. __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
  49. cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
  50. if (!cx) {
  51. return error;
  52. }
  53. pc += __GLX_SINGLE_HDR_SIZE;
  54. __GLX_SWAP_INT(pc + 0);
  55. __GLX_SWAP_INT(pc + 4);
  56. size = *(GLsizei *) (pc + 0);
  57. type = *(GLenum *) (pc + 4);
  58. if (cx->feedbackBufSize < size) {
  59. cx->feedbackBuf = (GLfloat *) realloc(cx->feedbackBuf,
  60. (size_t) size
  61. * __GLX_SIZE_FLOAT32);
  62. if (!cx->feedbackBuf) {
  63. cl->client->errorValue = size;
  64. return BadAlloc;
  65. }
  66. cx->feedbackBufSize = size;
  67. }
  68. glFeedbackBuffer(size, type, cx->feedbackBuf);
  69. cx->hasUnflushedCommands = GL_TRUE;
  70. return Success;
  71. }
  72. int
  73. __glXDispSwap_SelectBuffer(__GLXclientState * cl, GLbyte * pc)
  74. {
  75. ClientPtr client = cl->client;
  76. __GLXcontext *cx;
  77. GLsizei size;
  78. __GLX_DECLARE_SWAP_VARIABLES;
  79. int error;
  80. REQUEST_FIXED_SIZE(xGLXSingleReq, 4);
  81. __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
  82. cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
  83. if (!cx) {
  84. return error;
  85. }
  86. pc += __GLX_SINGLE_HDR_SIZE;
  87. __GLX_SWAP_INT(pc + 0);
  88. size = *(GLsizei *) (pc + 0);
  89. if (cx->selectBufSize < size) {
  90. cx->selectBuf = (GLuint *) realloc(cx->selectBuf,
  91. (size_t) size * __GLX_SIZE_CARD32);
  92. if (!cx->selectBuf) {
  93. cl->client->errorValue = size;
  94. return BadAlloc;
  95. }
  96. cx->selectBufSize = size;
  97. }
  98. glSelectBuffer(size, cx->selectBuf);
  99. cx->hasUnflushedCommands = GL_TRUE;
  100. return Success;
  101. }
  102. int
  103. __glXDispSwap_RenderMode(__GLXclientState * cl, GLbyte * pc)
  104. {
  105. ClientPtr client = cl->client;
  106. __GLXcontext *cx;
  107. xGLXRenderModeReply reply;
  108. GLint nitems = 0, retBytes = 0, retval, newModeCheck;
  109. GLubyte *retBuffer = NULL;
  110. GLenum newMode;
  111. __GLX_DECLARE_SWAP_VARIABLES;
  112. __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
  113. int error;
  114. REQUEST_FIXED_SIZE(xGLXSingleReq, 4);
  115. __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
  116. cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
  117. if (!cx) {
  118. return error;
  119. }
  120. pc += __GLX_SINGLE_HDR_SIZE;
  121. __GLX_SWAP_INT(pc);
  122. newMode = *(GLenum *) pc;
  123. retval = glRenderMode(newMode);
  124. /* Check that render mode worked */
  125. glGetIntegerv(GL_RENDER_MODE, &newModeCheck);
  126. if (newModeCheck != newMode) {
  127. /* Render mode change failed. Bail */
  128. newMode = newModeCheck;
  129. goto noChangeAllowed;
  130. }
  131. /*
  132. ** Render mode might have still failed if we get here. But in this
  133. ** case we can't really tell, nor does it matter. If it did fail, it
  134. ** will return 0, and thus we won't send any data across the wire.
  135. */
  136. switch (cx->renderMode) {
  137. case GL_RENDER:
  138. cx->renderMode = newMode;
  139. break;
  140. case GL_FEEDBACK:
  141. if (retval < 0) {
  142. /* Overflow happened. Copy the entire buffer */
  143. nitems = cx->feedbackBufSize;
  144. }
  145. else {
  146. nitems = retval;
  147. }
  148. retBytes = nitems * __GLX_SIZE_FLOAT32;
  149. retBuffer = (GLubyte *) cx->feedbackBuf;
  150. __GLX_SWAP_FLOAT_ARRAY((GLbyte *) retBuffer, nitems);
  151. cx->renderMode = newMode;
  152. break;
  153. case GL_SELECT:
  154. if (retval < 0) {
  155. /* Overflow happened. Copy the entire buffer */
  156. nitems = cx->selectBufSize;
  157. }
  158. else {
  159. GLuint *bp = cx->selectBuf;
  160. GLint i;
  161. /*
  162. ** Figure out how many bytes of data need to be sent. Parse
  163. ** the selection buffer to determine this fact as the
  164. ** return value is the number of hits, not the number of
  165. ** items in the buffer.
  166. */
  167. nitems = 0;
  168. i = retval;
  169. while (--i >= 0) {
  170. GLuint n;
  171. /* Parse select data for this hit */
  172. n = *bp;
  173. bp += 3 + n;
  174. }
  175. nitems = bp - cx->selectBuf;
  176. }
  177. retBytes = nitems * __GLX_SIZE_CARD32;
  178. retBuffer = (GLubyte *) cx->selectBuf;
  179. __GLX_SWAP_INT_ARRAY((GLbyte *) retBuffer, nitems);
  180. cx->renderMode = newMode;
  181. break;
  182. }
  183. /*
  184. ** First reply is the number of elements returned in the feedback or
  185. ** selection array, as per the API for glRenderMode itself.
  186. */
  187. noChangeAllowed:;
  188. reply = (xGLXRenderModeReply) {
  189. .type = X_Reply,
  190. .sequenceNumber = client->sequence,
  191. .length = nitems,
  192. .retval = retval,
  193. .size = nitems,
  194. .newMode = newMode
  195. };
  196. __GLX_SWAP_SHORT(&reply.sequenceNumber);
  197. __GLX_SWAP_INT(&reply.length);
  198. __GLX_SWAP_INT(&reply.retval);
  199. __GLX_SWAP_INT(&reply.size);
  200. __GLX_SWAP_INT(&reply.newMode);
  201. WriteToClient(client, sz_xGLXRenderModeReply, &reply);
  202. if (retBytes) {
  203. WriteToClient(client, retBytes, retBuffer);
  204. }
  205. return Success;
  206. }
  207. int
  208. __glXDispSwap_Flush(__GLXclientState * cl, GLbyte * pc)
  209. {
  210. ClientPtr client = cl->client;
  211. __GLXcontext *cx;
  212. int error;
  213. __GLX_DECLARE_SWAP_VARIABLES;
  214. REQUEST_SIZE_MATCH(xGLXSingleReq);
  215. __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
  216. cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
  217. if (!cx) {
  218. return error;
  219. }
  220. glFlush();
  221. cx->hasUnflushedCommands = GL_FALSE;
  222. return Success;
  223. }
  224. int
  225. __glXDispSwap_Finish(__GLXclientState * cl, GLbyte * pc)
  226. {
  227. ClientPtr client = cl->client;
  228. __GLXcontext *cx;
  229. int error;
  230. __GLX_DECLARE_SWAP_VARIABLES;
  231. REQUEST_SIZE_MATCH(xGLXSingleReq);
  232. __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
  233. cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
  234. if (!cx) {
  235. return error;
  236. }
  237. /* Do a local glFinish */
  238. glFinish();
  239. cx->hasUnflushedCommands = GL_FALSE;
  240. /* Send empty reply packet to indicate finish is finished */
  241. __GLX_BEGIN_REPLY(0);
  242. __GLX_PUT_RETVAL(0);
  243. __GLX_SWAP_REPLY_HEADER();
  244. __GLX_SEND_HEADER();
  245. return Success;
  246. }
  247. int
  248. __glXDispSwap_GetString(__GLXclientState * cl, GLbyte * pc)
  249. {
  250. return DoGetString(cl, pc, GL_TRUE);
  251. }