📄 xm_dd.c
字号:
/* clear back color buffer */ struct gl_renderbuffer *backRb = ctx->DrawBuffer->Attachment[BUFFER_BACK_LEFT].Renderbuffer; if (b->backxrb == xmesa_renderbuffer(backRb)) { /* renderbuffer is not wrapped - great! */ b->backxrb->clearFunc(ctx, b->backxrb, x, y, width, height); buffers &= ~BUFFER_BIT_BACK_LEFT; } } } } if (buffers) _swrast_Clear(ctx, buffers);}#ifndef XFree86Server/* XXX these functions haven't been tested in the Xserver environment *//** * Check if we can do an optimized glDrawPixels into an 8R8G8B visual. */static GLbooleancan_do_DrawPixels_8R8G8B(GLcontext *ctx, GLenum format, GLenum type){ if (format == GL_BGRA && type == GL_UNSIGNED_BYTE && ctx->DrawBuffer && ctx->DrawBuffer->Name == 0 && ctx->Pixel.ZoomX == 1.0 && /* no zooming */ ctx->Pixel.ZoomY == 1.0 && ctx->_ImageTransferState == 0 /* no color tables, scale/bias, etc */) { const SWcontext *swrast = SWRAST_CONTEXT(ctx); if (swrast->NewState) _swrast_validate_derived( ctx ); if ((swrast->_RasterMask & ~CLIP_BIT) == 0) /* no blend, z-test, etc */ { struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; if (rb) { struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb->Wrapped); if (xrb && xrb->pixmap && /* drawing to pixmap or window */ xrb->Base.AlphaBits == 0) { return GL_TRUE; } } } } return GL_FALSE;}/** * This function implements glDrawPixels() with an XPutImage call when * drawing to the front buffer (X Window drawable). * The image format must be GL_BGRA to match the PF_8R8G8B pixel format. */static voidxmesa_DrawPixels_8R8G8B( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels ){ if (can_do_DrawPixels_8R8G8B(ctx, format, type)) { const SWcontext *swrast = SWRAST_CONTEXT( ctx ); struct gl_pixelstore_attrib clippedUnpack = *unpack; int dstX = x; int dstY = y; int w = width; int h = height; if (swrast->NewState) _swrast_validate_derived( ctx ); if (unpack->BufferObj->Name) { /* unpack from PBO */ GLubyte *buf; if (!_mesa_validate_pbo_access(2, unpack, width, height, 1, format, type, pixels)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels(invalid PBO access)"); return; } buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, GL_READ_ONLY_ARB, unpack->BufferObj); if (!buf) { /* buffer is already mapped - that's an error */ _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels(PBO is mapped)"); return; } pixels = ADD_POINTERS(buf, pixels); } if (_mesa_clip_drawpixels(ctx, &dstX, &dstY, &w, &h, &clippedUnpack)) { const XMesaContext xmesa = XMESA_CONTEXT(ctx); XMesaDisplay *dpy = xmesa->xm_visual->display; XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); const XMesaGC gc = xmbuf->cleargc; /* effected by glColorMask */ struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]->Wrapped); const int srcX = clippedUnpack.SkipPixels; const int srcY = clippedUnpack.SkipRows; const int rowLength = clippedUnpack.RowLength; XMesaImage ximage; ASSERT(xmesa->xm_visual->dithered_pf == PF_8R8G8B); ASSERT(xmesa->xm_visual->undithered_pf == PF_8R8G8B); ASSERT(dpy); ASSERT(gc); /* This is a little tricky since all coordinates up to now have * been in the OpenGL bottom-to-top orientation. X is top-to-bottom * so we have to carefully compute the Y coordinates/addresses here. */ MEMSET(&ximage, 0, sizeof(XMesaImage)); ximage.width = width; ximage.height = height; ximage.format = ZPixmap; ximage.data = (char *) pixels + ((srcY + h - 1) * rowLength + srcX) * 4; ximage.byte_order = LSBFirst; ximage.bitmap_unit = 32; ximage.bitmap_bit_order = LSBFirst; ximage.bitmap_pad = 32; ximage.depth = 32; ximage.bits_per_pixel = 32; ximage.bytes_per_line = -rowLength * 4; /* negative to flip image */ /* it seems we don't need to set the ximage.red/green/blue_mask fields */ /* flip Y axis for dest position */ dstY = YFLIP(xrb, dstY) - h + 1; XPutImage(dpy, xrb->pixmap, gc, &ximage, 0, 0, dstX, dstY, w, h); } if (unpack->BufferObj->Name) { ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, unpack->BufferObj); } } else { /* software fallback */ _swrast_DrawPixels(ctx, x, y, width, height, format, type, unpack, pixels); }}/** * Check if we can do an optimized glDrawPixels into an 5R6G5B visual. */static GLbooleancan_do_DrawPixels_5R6G5B(GLcontext *ctx, GLenum format, GLenum type){ if (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 && !ctx->Color.DitherFlag && /* no dithering */ ctx->DrawBuffer && ctx->DrawBuffer->Name == 0 && ctx->Pixel.ZoomX == 1.0 && /* no zooming */ ctx->Pixel.ZoomY == 1.0 && ctx->_ImageTransferState == 0 /* no color tables, scale/bias, etc */) { const SWcontext *swrast = SWRAST_CONTEXT(ctx); if (swrast->NewState) _swrast_validate_derived( ctx ); if ((swrast->_RasterMask & ~CLIP_BIT) == 0) /* no blend, z-test, etc */ { struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; if (rb) { struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb->Wrapped); if (xrb && xrb->pixmap && /* drawing to pixmap or window */ xrb->Base.AlphaBits == 0) { return GL_TRUE; } } } } return GL_FALSE;}/** * This function implements glDrawPixels() with an XPutImage call when * drawing to the front buffer (X Window drawable). The image format * must be GL_RGB and image type must be GL_UNSIGNED_SHORT_5_6_5 to * match the PF_5R6G5B pixel format. */static voidxmesa_DrawPixels_5R6G5B( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels ){ if (can_do_DrawPixels_5R6G5B(ctx, format, type)) { const SWcontext *swrast = SWRAST_CONTEXT( ctx ); struct gl_pixelstore_attrib clippedUnpack = *unpack; int dstX = x; int dstY = y; int w = width; int h = height; if (swrast->NewState) _swrast_validate_derived( ctx ); if (unpack->BufferObj->Name) { /* unpack from PBO */ GLubyte *buf; if (!_mesa_validate_pbo_access(2, unpack, width, height, 1, format, type, pixels)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels(invalid PBO access)"); return; } buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, GL_READ_ONLY_ARB, unpack->BufferObj); if (!buf) { /* buffer is already mapped - that's an error */ _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels(PBO is mapped)"); return; } pixels = ADD_POINTERS(buf, pixels); } if (_mesa_clip_drawpixels(ctx, &dstX, &dstY, &w, &h, &clippedUnpack)) { const XMesaContext xmesa = XMESA_CONTEXT(ctx); XMesaDisplay *dpy = xmesa->xm_visual->display; XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); const XMesaGC gc = xmbuf->cleargc; /* effected by glColorMask */ struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]->Wrapped); const int srcX = clippedUnpack.SkipPixels; const int srcY = clippedUnpack.SkipRows; const int rowLength = clippedUnpack.RowLength; XMesaImage ximage; ASSERT(xmesa->xm_visual->undithered_pf == PF_5R6G5B); ASSERT(dpy); ASSERT(gc); /* This is a little tricky since all coordinates up to now have * been in the OpenGL bottom-to-top orientation. X is top-to-bottom * so we have to carefully compute the Y coordinates/addresses here. */ MEMSET(&ximage, 0, sizeof(XMesaImage)); ximage.width = width; ximage.height = height; ximage.format = ZPixmap; ximage.data = (char *) pixels + ((srcY + h - 1) * rowLength + srcX) * 2; ximage.byte_order = LSBFirst; ximage.bitmap_unit = 16; ximage.bitmap_bit_order = LSBFirst; ximage.bitmap_pad = 16; ximage.depth = 16; ximage.bits_per_pixel = 16; ximage.bytes_per_line = -rowLength * 2; /* negative to flip image */ /* it seems we don't need to set the ximage.red/green/blue_mask fields */ /* flip Y axis for dest position */ dstY = YFLIP(xrb, dstY) - h + 1; XPutImage(dpy, xrb->pixmap, gc, &ximage, 0, 0, dstX, dstY, w, h); } if (unpack->BufferObj->Name) { ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, unpack->BufferObj); } } else { /* software fallback */ _swrast_DrawPixels(ctx, x, y, width, height, format, type, unpack, pixels); }}/** * Determine if we can do an optimized glCopyPixels. */static GLbooleancan_do_CopyPixels(GLcontext *ctx, GLenum type){ if (type == GL_COLOR && ctx->_ImageTransferState == 0 && /* no color tables, scale/bias, etc */ ctx->Pixel.ZoomX == 1.0 && /* no zooming */ ctx->Pixel.ZoomY == 1.0 && ctx->Color.DrawBuffer[0] == GL_FRONT && /* copy to front buf */ ctx->Pixel.ReadBuffer == GL_FRONT && /* copy from front buf */ ctx->ReadBuffer->_ColorReadBuffer && ctx->DrawBuffer->_ColorDrawBuffers[0]) { const SWcontext *swrast = SWRAST_CONTEXT( ctx ); if (swrast->NewState) _swrast_validate_derived( ctx ); if ((swrast->_RasterMask & ~CLIP_BIT) == 0x0 && ctx->ReadBuffer && ctx->ReadBuffer->_ColorReadBuffer && ctx->DrawBuffer && ctx->DrawBuffer->_ColorDrawBuffers[0]) { struct xmesa_renderbuffer *srcXrb = xmesa_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer->Wrapped); struct xmesa_renderbuffer *dstXrb = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]->Wrapped); if (srcXrb->pixmap && dstXrb->pixmap) { return GL_TRUE; } } } return GL_FALSE;}/** * Implement glCopyPixels for the front color buffer (or back buffer Pixmap) * for the color buffer. Don't support zooming, pixel transfer, etc. * We do support copying from one window to another, ala glXMakeCurrentRead. */static voidxmesa_CopyPixels( GLcontext *ctx, GLint srcx, GLint srcy, GLsizei width, GLsizei height, GLint destx, GLint desty, GLenum type ){ if (can_do_CopyPixels(ctx, type)) { const XMesaContext xmesa = XMESA_CONTEXT(ctx); XMesaDisplay *dpy = xmesa->xm_visual->display; XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); const XMesaGC gc = xmbuf->cleargc; /* effected by glColorMask */ struct xmesa_renderbuffer *srcXrb = xmesa_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer->Wrapped); struct xmesa_renderbuffer *dstXrb = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]->Wrapped); ASSERT(dpy); ASSERT(gc); /* Note: we don't do any special clipping work here. We could, * but X will do it for us. */ srcy = YFLIP(srcXrb, srcy) - height + 1; desty = YFLIP(dstXrb, desty) - height + 1; XCopyArea(dpy, srcXrb->pixmap, dstXrb->pixmap, gc, srcx, srcy, width, height, destx, desty); } else { _swrast_CopyPixels(ctx, srcx, srcy, width, height, destx, desty, type ); }}#endif /* XFree86Server *//* * Every driver should implement a GetString function in order to * return a meaningful GL_RENDERER string. */static const GLubyte *get_string( GLcontext *ctx, GLenum name ){ (void) ctx; switch (name) { case GL_RENDERER:#ifdef XFree86Server return (const GLubyte *) "Mesa GLX Indirect";#else return (const GLubyte *) "Mesa X11";#endif case GL_VENDOR:#ifdef XFree86Server return (const GLubyte *) "Mesa project: www.mesa3d.org";#else return NULL;#endif default: return NULL; }}/* * We implement the glEnable function only because we care about * dither enable/disable. */static voidenable( GLcontext *ctx, GLenum pname, GLboolean state ){ const XMesaContext xmesa = XMESA_CONTEXT(ctx); switch (pname) { case GL_DITHER: if (state) xmesa->pixelformat = xmesa->xm_visual->dithered_pf; else xmesa->pixelformat = xmesa->xm_visual->undithered_pf;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -