Source code of Windows XP (NT5)
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.

429 lines
11 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. #include "devlock.h"
  4. GLboolean __glGenCheckDrawPixelArgs(__GLcontext *gc,
  5. GLsizei width, GLsizei height, GLenum format, GLenum type)
  6. {
  7. GLboolean index;
  8. if ((width < 0) || (height < 0)) {
  9. __glSetError(GL_INVALID_VALUE);
  10. return GL_FALSE;
  11. }
  12. switch (format) {
  13. case GL_STENCIL_INDEX:
  14. if (!gc->modes.stencilBits) {
  15. __glSetError(GL_INVALID_OPERATION);
  16. return GL_FALSE;
  17. }
  18. if (!gc->modes.haveStencilBuffer) {
  19. LazyAllocateStencil(gc);
  20. if (!gc->stencilBuffer.buf.base) {
  21. return GL_FALSE;
  22. }
  23. }
  24. index = GL_TRUE;
  25. break;
  26. case GL_COLOR_INDEX:
  27. index = GL_TRUE;
  28. break;
  29. case GL_RED:
  30. case GL_GREEN:
  31. case GL_BLUE:
  32. case GL_ALPHA:
  33. case GL_RGB:
  34. case GL_RGBA:
  35. case GL_LUMINANCE:
  36. case GL_LUMINANCE_ALPHA:
  37. #ifdef GL_EXT_bgra
  38. case GL_BGRA_EXT:
  39. case GL_BGR_EXT:
  40. #endif
  41. if (gc->modes.colorIndexMode) {
  42. /* Can't convert RGB to color index */
  43. __glSetError(GL_INVALID_OPERATION);
  44. return GL_FALSE;
  45. }
  46. index = GL_FALSE;
  47. break;
  48. case GL_DEPTH_COMPONENT:
  49. if (!gc->modes.depthBits) {
  50. __glSetError(GL_INVALID_OPERATION);
  51. return GL_FALSE;
  52. }
  53. if (!gc->modes.haveDepthBuffer) {
  54. LazyAllocateDepth(gc);
  55. if (!gc->depthBuffer.buf.base) {
  56. return GL_FALSE;
  57. }
  58. }
  59. index = GL_FALSE;
  60. break;
  61. default:
  62. __glSetError(GL_INVALID_ENUM);
  63. return GL_FALSE;
  64. }
  65. switch (type) {
  66. case GL_BITMAP:
  67. if (!index) {
  68. __glSetError(GL_INVALID_ENUM);
  69. return GL_FALSE;
  70. }
  71. break;
  72. case GL_BYTE:
  73. case GL_UNSIGNED_BYTE:
  74. case GL_SHORT:
  75. case GL_UNSIGNED_SHORT:
  76. case GL_INT:
  77. case GL_UNSIGNED_INT:
  78. case GL_FLOAT:
  79. break;
  80. default:
  81. __glSetError(GL_INVALID_ENUM);
  82. return GL_FALSE;
  83. }
  84. return GL_TRUE;
  85. }
  86. GLboolean __glGenCheckReadPixelArgs(__GLcontext *gc,
  87. GLsizei width, GLsizei height, GLenum format, GLenum type)
  88. {
  89. if ((width < 0) || (height < 0)) {
  90. __glSetError(GL_INVALID_VALUE);
  91. return GL_FALSE;
  92. }
  93. switch (format) {
  94. case GL_STENCIL_INDEX:
  95. if (!gc->modes.stencilBits) {
  96. __glSetError(GL_INVALID_OPERATION);
  97. return GL_FALSE;
  98. }
  99. if (!gc->modes.haveStencilBuffer) {
  100. LazyAllocateStencil(gc);
  101. if (!gc->stencilBuffer.buf.base) {
  102. return GL_FALSE;
  103. }
  104. }
  105. break;
  106. case GL_COLOR_INDEX:
  107. if (gc->modes.rgbMode) {
  108. /* Can't convert RGB to color index */
  109. __glSetError(GL_INVALID_OPERATION);
  110. return GL_FALSE;
  111. }
  112. break;
  113. case GL_DEPTH_COMPONENT:
  114. if (!gc->modes.depthBits) {
  115. __glSetError(GL_INVALID_OPERATION);
  116. return GL_FALSE;
  117. }
  118. if (!gc->modes.haveDepthBuffer) {
  119. LazyAllocateDepth(gc);
  120. if (!gc->depthBuffer.buf.base) {
  121. return GL_FALSE;
  122. }
  123. }
  124. break;
  125. case GL_RED:
  126. case GL_GREEN:
  127. case GL_BLUE:
  128. case GL_ALPHA:
  129. case GL_RGB:
  130. case GL_RGBA:
  131. case GL_LUMINANCE:
  132. case GL_LUMINANCE_ALPHA:
  133. #ifdef GL_EXT_bgra
  134. case GL_BGRA_EXT:
  135. case GL_BGR_EXT:
  136. #endif
  137. break;
  138. default:
  139. __glSetError(GL_INVALID_ENUM);
  140. return GL_FALSE;
  141. }
  142. switch (type) {
  143. case GL_BITMAP:
  144. if (format != GL_STENCIL_INDEX && format != GL_COLOR_INDEX) {
  145. __glSetError(GL_INVALID_OPERATION);
  146. return GL_FALSE;
  147. }
  148. break;
  149. case GL_BYTE:
  150. case GL_UNSIGNED_BYTE:
  151. case GL_SHORT:
  152. case GL_UNSIGNED_SHORT:
  153. case GL_INT:
  154. case GL_UNSIGNED_INT:
  155. case GL_FLOAT:
  156. break;
  157. default:
  158. __glSetError(GL_INVALID_ENUM);
  159. return GL_FALSE;
  160. }
  161. return GL_TRUE;
  162. }
  163. #ifdef NT
  164. void APIPRIVATE __glim_DrawPixels(GLsizei width, GLsizei height, GLenum format,
  165. GLenum type, const GLvoid *pixels, GLboolean _IsDlist)
  166. #else
  167. void APIPRIVATE __glim_DrawPixels(GLsizei width, GLsizei height, GLenum format,
  168. GLenum type, const GLvoid *pixels)
  169. #endif
  170. {
  171. __GL_SETUP();
  172. GLuint beginMode;
  173. BOOL bResetViewportAdj = FALSE;
  174. beginMode = gc->beginMode;
  175. if (beginMode != __GL_NOT_IN_BEGIN) {
  176. if (beginMode == __GL_NEED_VALIDATE) {
  177. (*gc->procs.validate)(gc);
  178. gc->beginMode = __GL_NOT_IN_BEGIN;
  179. __glim_DrawPixels(width, height, format,
  180. type, pixels, _IsDlist);
  181. return;
  182. } else {
  183. __glSetError(GL_INVALID_OPERATION);
  184. return;
  185. }
  186. }
  187. if (!__glGenCheckDrawPixelArgs(gc, width, height, format, type)) return;
  188. if (!gc->state.current.validRasterPos) {
  189. return;
  190. }
  191. if (gc->renderMode == GL_FEEDBACK) {
  192. __glFeedbackDrawPixels(gc, &gc->state.current.rasterPos);
  193. return;
  194. }
  195. if (gc->renderMode != GL_RENDER)
  196. return;
  197. #ifdef _MCD_
  198. // If MCD context, give driver first crack at call. If it succeeds,
  199. // return. Otherwise, continue on with the generic version.
  200. {
  201. __GLGENcontext *gengc = (__GLGENcontext *) gc;
  202. if (gengc->pMcdState) {
  203. if (GenMcdDrawPix(gengc, width, height, format, type,
  204. (VOID *) pixels, _IsDlist))
  205. return;
  206. // If MCD kicked back, now is the time to grab the device lock if
  207. // needed. If we can't, abandon the call.
  208. if (!glsrvLazyGrabSurfaces(gengc, RENDER_LOCK_FLAGS))
  209. return;
  210. // We may need to temporarily reset the viewport adjust values
  211. // before calling simulations. If GenMcdResetViewportAdj returns
  212. // TRUE, the viewport is changed and we need restore later with
  213. // VP_NOBIAS.
  214. bResetViewportAdj = GenMcdResetViewportAdj(gc, VP_FIXBIAS);
  215. }
  216. }
  217. #endif
  218. #ifdef NT
  219. if (_IsDlist)
  220. {
  221. (*gc->procs.drawPixels)(gc, width, height, format, type, pixels, GL_TRUE);
  222. }
  223. else
  224. {
  225. #endif
  226. (*gc->procs.drawPixels)(gc, width, height, format, type, pixels, GL_FALSE);
  227. #ifdef NT
  228. }
  229. #endif
  230. // Restore viewport values if needed.
  231. if (bResetViewportAdj)
  232. {
  233. GenMcdResetViewportAdj(gc, VP_NOBIAS);
  234. }
  235. }
  236. void APIPRIVATE __glim_ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
  237. GLenum format, GLenum type, GLvoid *buf)
  238. {
  239. __GL_SETUP();
  240. GLuint beginMode;
  241. BOOL bResetViewportAdj = FALSE;
  242. beginMode = gc->beginMode;
  243. if (beginMode != __GL_NOT_IN_BEGIN) {
  244. if (beginMode == __GL_NEED_VALIDATE) {
  245. (*gc->procs.validate)(gc);
  246. gc->beginMode = __GL_NOT_IN_BEGIN;
  247. __glim_ReadPixels(x,y,width,height,
  248. format,type,buf);
  249. return;
  250. } else {
  251. __glSetError(GL_INVALID_OPERATION);
  252. return;
  253. }
  254. }
  255. if (!__glGenCheckReadPixelArgs(gc, width, height, format, type))
  256. return;
  257. #ifdef _MCD_
  258. // If MCD context, give driver first crack at call. If it succeeds,
  259. // return. Otherwise, continue on with the generic version.
  260. {
  261. __GLGENcontext *gengc = (__GLGENcontext *) gc;
  262. if (gengc->pMcdState) {
  263. if (GenMcdReadPix(gengc, x, y, width, height, format, type, buf))
  264. return;
  265. // If MCD kicked back, now is the time to grab the device lock if
  266. // needed. If we can't, abandon the call.
  267. if (!glsrvLazyGrabSurfaces(gengc,
  268. COLOR_LOCK_FLAGS | DEPTH_LOCK_FLAGS))
  269. return;
  270. // We may need to temporarily reset the viewport adjust values
  271. // before calling simulations. If GenMcdResetViewportAdj returns
  272. // TRUE, the viewport is changed and we need restore later with
  273. // VP_NOBIAS.
  274. bResetViewportAdj = GenMcdResetViewportAdj(gc, VP_FIXBIAS);
  275. }
  276. }
  277. #endif
  278. (*gc->procs.readPixels)(gc, x, y, width, height, format, type, buf);
  279. // Restore viewport values if needed.
  280. if (bResetViewportAdj)
  281. {
  282. GenMcdResetViewportAdj(gc, VP_NOBIAS);
  283. }
  284. }
  285. void APIPRIVATE __glim_CopyPixels(GLint x, GLint y, GLsizei width, GLsizei height,
  286. GLenum type)
  287. {
  288. GLenum format;
  289. __GL_SETUP();
  290. GLuint beginMode;
  291. BOOL bResetViewportAdj = FALSE;
  292. beginMode = gc->beginMode;
  293. if (beginMode != __GL_NOT_IN_BEGIN) {
  294. if (beginMode == __GL_NEED_VALIDATE) {
  295. (*gc->procs.validate)(gc);
  296. gc->beginMode = __GL_NOT_IN_BEGIN;
  297. __glim_CopyPixels(x,y,width,height,type);
  298. return;
  299. } else {
  300. __glSetError(GL_INVALID_OPERATION);
  301. return;
  302. }
  303. }
  304. if ((width < 0) || (height < 0)) {
  305. __glSetError(GL_INVALID_VALUE);
  306. return;
  307. }
  308. switch (type) {
  309. case GL_STENCIL:
  310. if (!gc->modes.stencilBits) {
  311. __glSetError(GL_INVALID_OPERATION);
  312. return;
  313. }
  314. if (!gc->modes.haveStencilBuffer) {
  315. LazyAllocateStencil(gc);
  316. if (!gc->stencilBuffer.buf.base) {
  317. return;
  318. }
  319. }
  320. format = GL_STENCIL_INDEX;
  321. break;
  322. case GL_COLOR:
  323. if (gc->modes.rgbMode) {
  324. format = GL_RGBA;
  325. } else {
  326. format = GL_COLOR_INDEX;
  327. }
  328. break;
  329. case GL_DEPTH:
  330. if (!gc->modes.depthBits) {
  331. __glSetError(GL_INVALID_OPERATION);
  332. return;
  333. }
  334. if (!gc->modes.haveDepthBuffer) {
  335. LazyAllocateDepth(gc);
  336. if (!gc->depthBuffer.buf.base) {
  337. return;
  338. }
  339. }
  340. format = GL_DEPTH_COMPONENT;
  341. break;
  342. default:
  343. __glSetError(GL_INVALID_ENUM);
  344. return;
  345. }
  346. if (!gc->state.current.validRasterPos) {
  347. return;
  348. }
  349. if (gc->renderMode == GL_FEEDBACK) {
  350. __glFeedbackCopyPixels(gc, &gc->state.current.rasterPos);
  351. return;
  352. }
  353. if (gc->renderMode != GL_RENDER)
  354. return;
  355. #ifdef _MCD_
  356. // If MCD context, give driver first crack at call. If it succeeds,
  357. // return. Otherwise, continue on with the generic version.
  358. {
  359. __GLGENcontext *gengc = (__GLGENcontext *) gc;
  360. if (gengc->pMcdState) {
  361. if (GenMcdCopyPix(gengc, x, y, width, height, type))
  362. return;
  363. // If MCD kicked back, now is the time to grab the device lock if
  364. // needed. If we can't, abandon the call.
  365. if (!glsrvLazyGrabSurfaces(gengc, RENDER_LOCK_FLAGS))
  366. return;
  367. // We may need to temporarily reset the viewport adjust values
  368. // before calling simulations. If GenMcdResetViewportAdj returns
  369. // TRUE, the viewport is changed and we need restore later with
  370. // VP_NOBIAS.
  371. bResetViewportAdj = GenMcdResetViewportAdj(gc, VP_FIXBIAS);
  372. }
  373. }
  374. #endif
  375. (*gc->procs.copyPixels)(gc, x, y, width, height, format);
  376. // Restore viewport values if needed.
  377. if (bResetViewportAdj)
  378. {
  379. GenMcdResetViewportAdj(gc, VP_NOBIAS);
  380. }
  381. }