#include "precomp.h" #pragma hdrstop #include "devlock.h" GLboolean __glGenCheckDrawPixelArgs(__GLcontext *gc, GLsizei width, GLsizei height, GLenum format, GLenum type) { GLboolean index; if ((width < 0) || (height < 0)) { __glSetError(GL_INVALID_VALUE); return GL_FALSE; } switch (format) { case GL_STENCIL_INDEX: if (!gc->modes.stencilBits) { __glSetError(GL_INVALID_OPERATION); return GL_FALSE; } if (!gc->modes.haveStencilBuffer) { LazyAllocateStencil(gc); if (!gc->stencilBuffer.buf.base) { return GL_FALSE; } } index = GL_TRUE; break; case GL_COLOR_INDEX: index = GL_TRUE; break; case GL_RED: case GL_GREEN: case GL_BLUE: case GL_ALPHA: case GL_RGB: case GL_RGBA: case GL_LUMINANCE: case GL_LUMINANCE_ALPHA: #ifdef GL_EXT_bgra case GL_BGRA_EXT: case GL_BGR_EXT: #endif if (gc->modes.colorIndexMode) { /* Can't convert RGB to color index */ __glSetError(GL_INVALID_OPERATION); return GL_FALSE; } index = GL_FALSE; break; case GL_DEPTH_COMPONENT: if (!gc->modes.depthBits) { __glSetError(GL_INVALID_OPERATION); return GL_FALSE; } if (!gc->modes.haveDepthBuffer) { LazyAllocateDepth(gc); if (!gc->depthBuffer.buf.base) { return GL_FALSE; } } index = GL_FALSE; break; default: __glSetError(GL_INVALID_ENUM); return GL_FALSE; } switch (type) { case GL_BITMAP: if (!index) { __glSetError(GL_INVALID_ENUM); return GL_FALSE; } break; case GL_BYTE: case GL_UNSIGNED_BYTE: case GL_SHORT: case GL_UNSIGNED_SHORT: case GL_INT: case GL_UNSIGNED_INT: case GL_FLOAT: break; default: __glSetError(GL_INVALID_ENUM); return GL_FALSE; } return GL_TRUE; } GLboolean __glGenCheckReadPixelArgs(__GLcontext *gc, GLsizei width, GLsizei height, GLenum format, GLenum type) { if ((width < 0) || (height < 0)) { __glSetError(GL_INVALID_VALUE); return GL_FALSE; } switch (format) { case GL_STENCIL_INDEX: if (!gc->modes.stencilBits) { __glSetError(GL_INVALID_OPERATION); return GL_FALSE; } if (!gc->modes.haveStencilBuffer) { LazyAllocateStencil(gc); if (!gc->stencilBuffer.buf.base) { return GL_FALSE; } } break; case GL_COLOR_INDEX: if (gc->modes.rgbMode) { /* Can't convert RGB to color index */ __glSetError(GL_INVALID_OPERATION); return GL_FALSE; } break; case GL_DEPTH_COMPONENT: if (!gc->modes.depthBits) { __glSetError(GL_INVALID_OPERATION); return GL_FALSE; } if (!gc->modes.haveDepthBuffer) { LazyAllocateDepth(gc); if (!gc->depthBuffer.buf.base) { return GL_FALSE; } } break; case GL_RED: case GL_GREEN: case GL_BLUE: case GL_ALPHA: case GL_RGB: case GL_RGBA: case GL_LUMINANCE: case GL_LUMINANCE_ALPHA: #ifdef GL_EXT_bgra case GL_BGRA_EXT: case GL_BGR_EXT: #endif break; default: __glSetError(GL_INVALID_ENUM); return GL_FALSE; } switch (type) { case GL_BITMAP: if (format != GL_STENCIL_INDEX && format != GL_COLOR_INDEX) { __glSetError(GL_INVALID_OPERATION); return GL_FALSE; } break; case GL_BYTE: case GL_UNSIGNED_BYTE: case GL_SHORT: case GL_UNSIGNED_SHORT: case GL_INT: case GL_UNSIGNED_INT: case GL_FLOAT: break; default: __glSetError(GL_INVALID_ENUM); return GL_FALSE; } return GL_TRUE; } #ifdef NT void APIPRIVATE __glim_DrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels, GLboolean _IsDlist) #else void APIPRIVATE __glim_DrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) #endif { __GL_SETUP(); GLuint beginMode; BOOL bResetViewportAdj = FALSE; beginMode = gc->beginMode; if (beginMode != __GL_NOT_IN_BEGIN) { if (beginMode == __GL_NEED_VALIDATE) { (*gc->procs.validate)(gc); gc->beginMode = __GL_NOT_IN_BEGIN; __glim_DrawPixels(width, height, format, type, pixels, _IsDlist); return; } else { __glSetError(GL_INVALID_OPERATION); return; } } if (!__glGenCheckDrawPixelArgs(gc, width, height, format, type)) return; if (!gc->state.current.validRasterPos) { return; } if (gc->renderMode == GL_FEEDBACK) { __glFeedbackDrawPixels(gc, &gc->state.current.rasterPos); return; } if (gc->renderMode != GL_RENDER) return; #ifdef _MCD_ // If MCD context, give driver first crack at call. If it succeeds, // return. Otherwise, continue on with the generic version. { __GLGENcontext *gengc = (__GLGENcontext *) gc; if (gengc->pMcdState) { if (GenMcdDrawPix(gengc, width, height, format, type, (VOID *) pixels, _IsDlist)) return; // If MCD kicked back, now is the time to grab the device lock if // needed. If we can't, abandon the call. if (!glsrvLazyGrabSurfaces(gengc, RENDER_LOCK_FLAGS)) return; // We may need to temporarily reset the viewport adjust values // before calling simulations. If GenMcdResetViewportAdj returns // TRUE, the viewport is changed and we need restore later with // VP_NOBIAS. bResetViewportAdj = GenMcdResetViewportAdj(gc, VP_FIXBIAS); } } #endif #ifdef NT if (_IsDlist) { (*gc->procs.drawPixels)(gc, width, height, format, type, pixels, GL_TRUE); } else { #endif (*gc->procs.drawPixels)(gc, width, height, format, type, pixels, GL_FALSE); #ifdef NT } #endif // Restore viewport values if needed. if (bResetViewportAdj) { GenMcdResetViewportAdj(gc, VP_NOBIAS); } } void APIPRIVATE __glim_ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *buf) { __GL_SETUP(); GLuint beginMode; BOOL bResetViewportAdj = FALSE; beginMode = gc->beginMode; if (beginMode != __GL_NOT_IN_BEGIN) { if (beginMode == __GL_NEED_VALIDATE) { (*gc->procs.validate)(gc); gc->beginMode = __GL_NOT_IN_BEGIN; __glim_ReadPixels(x,y,width,height, format,type,buf); return; } else { __glSetError(GL_INVALID_OPERATION); return; } } if (!__glGenCheckReadPixelArgs(gc, width, height, format, type)) return; #ifdef _MCD_ // If MCD context, give driver first crack at call. If it succeeds, // return. Otherwise, continue on with the generic version. { __GLGENcontext *gengc = (__GLGENcontext *) gc; if (gengc->pMcdState) { if (GenMcdReadPix(gengc, x, y, width, height, format, type, buf)) return; // If MCD kicked back, now is the time to grab the device lock if // needed. If we can't, abandon the call. if (!glsrvLazyGrabSurfaces(gengc, COLOR_LOCK_FLAGS | DEPTH_LOCK_FLAGS)) return; // We may need to temporarily reset the viewport adjust values // before calling simulations. If GenMcdResetViewportAdj returns // TRUE, the viewport is changed and we need restore later with // VP_NOBIAS. bResetViewportAdj = GenMcdResetViewportAdj(gc, VP_FIXBIAS); } } #endif (*gc->procs.readPixels)(gc, x, y, width, height, format, type, buf); // Restore viewport values if needed. if (bResetViewportAdj) { GenMcdResetViewportAdj(gc, VP_NOBIAS); } } void APIPRIVATE __glim_CopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type) { GLenum format; __GL_SETUP(); GLuint beginMode; BOOL bResetViewportAdj = FALSE; beginMode = gc->beginMode; if (beginMode != __GL_NOT_IN_BEGIN) { if (beginMode == __GL_NEED_VALIDATE) { (*gc->procs.validate)(gc); gc->beginMode = __GL_NOT_IN_BEGIN; __glim_CopyPixels(x,y,width,height,type); return; } else { __glSetError(GL_INVALID_OPERATION); return; } } if ((width < 0) || (height < 0)) { __glSetError(GL_INVALID_VALUE); return; } switch (type) { case GL_STENCIL: if (!gc->modes.stencilBits) { __glSetError(GL_INVALID_OPERATION); return; } if (!gc->modes.haveStencilBuffer) { LazyAllocateStencil(gc); if (!gc->stencilBuffer.buf.base) { return; } } format = GL_STENCIL_INDEX; break; case GL_COLOR: if (gc->modes.rgbMode) { format = GL_RGBA; } else { format = GL_COLOR_INDEX; } break; case GL_DEPTH: if (!gc->modes.depthBits) { __glSetError(GL_INVALID_OPERATION); return; } if (!gc->modes.haveDepthBuffer) { LazyAllocateDepth(gc); if (!gc->depthBuffer.buf.base) { return; } } format = GL_DEPTH_COMPONENT; break; default: __glSetError(GL_INVALID_ENUM); return; } if (!gc->state.current.validRasterPos) { return; } if (gc->renderMode == GL_FEEDBACK) { __glFeedbackCopyPixels(gc, &gc->state.current.rasterPos); return; } if (gc->renderMode != GL_RENDER) return; #ifdef _MCD_ // If MCD context, give driver first crack at call. If it succeeds, // return. Otherwise, continue on with the generic version. { __GLGENcontext *gengc = (__GLGENcontext *) gc; if (gengc->pMcdState) { if (GenMcdCopyPix(gengc, x, y, width, height, type)) return; // If MCD kicked back, now is the time to grab the device lock if // needed. If we can't, abandon the call. if (!glsrvLazyGrabSurfaces(gengc, RENDER_LOCK_FLAGS)) return; // We may need to temporarily reset the viewport adjust values // before calling simulations. If GenMcdResetViewportAdj returns // TRUE, the viewport is changed and we need restore later with // VP_NOBIAS. bResetViewportAdj = GenMcdResetViewportAdj(gc, VP_FIXBIAS); } } #endif (*gc->procs.copyPixels)(gc, x, y, width, height, format); // Restore viewport values if needed. if (bResetViewportAdj) { GenMcdResetViewportAdj(gc, VP_NOBIAS); } }