/**
 * Reallocate renderbuffer storage for back color buffer.
 * Called via gl_renderbuffer::AllocStorage()
 */
static GLboolean
xmesa_alloc_back_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
                         GLenum internalFormat, GLuint width, GLuint height)
{
   struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb);

   /* reallocate the back buffer XImage or Pixmap */
   assert(xrb->Parent);
   alloc_back_buffer(xrb->Parent, width, height);

   /* same as front buffer */
   /* XXX why is this here? */
   (void) xmesa_alloc_front_storage(ctx, rb, internalFormat, width, height);

   /* plus... */
   if (xrb->ximage) {
      /* Needed by PIXELADDR1 macro */
      xrb->width1 = xrb->ximage->bytes_per_line;
      xrb->origin1 = (GLubyte *) xrb->ximage->data + xrb->width1 * (height - 1);

      /* Needed by PIXELADDR2 macro */
      xrb->width2 = xrb->ximage->bytes_per_line / 2;
      xrb->origin2 = (GLushort *) xrb->ximage->data + xrb->width2 * (height - 1);

      /* Needed by PIXELADDR3 macro */
      xrb->width3 = xrb->ximage->bytes_per_line;
      xrb->origin3 = (GLubyte *) xrb->ximage->data + xrb->width3 * (height - 1);

      /* Needed by PIXELADDR4 macro */
      xrb->width4 = xrb->ximage->width;
      xrb->origin4 = (GLuint *) xrb->ximage->data + xrb->width4 * (height - 1);
   }
   else {
      /* out of memory or buffer size is 0 x 0 */
      xrb->width1 = xrb->width2 = xrb->width3 = xrb->width4 = 0;
      xrb->origin1 = NULL;
      xrb->origin2 = NULL;
      xrb->origin3 = NULL;
      xrb->origin4 = NULL;
   }

   return GL_TRUE;
}
Exemple #2
0
/**
 * Reallocate renderbuffer storage for front color buffer.
 * Called via gl_renderbuffer::AllocStorage()
 */
static GLboolean
xmesa_alloc_front_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
                          GLenum internalFormat, GLuint width, GLuint height)
{
    struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb);

    /* just clear these to be sure we don't accidentally use them */
    xrb->origin2 = NULL;
    xrb->origin3 = NULL;
    xrb->origin4 = NULL;

    /* for the FLIP macro: */
    xrb->bottom = height - 1;

    rb->Width = width;
    rb->Height = height;
    rb->InternalFormat = internalFormat;

    return GL_TRUE;
}
Exemple #3
0
/**
 * Called via ctx->Driver.UnmapRenderbuffer()
 */
void
xmesa_UnmapRenderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb)
{
    struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb);

    if (xrb->Base.Base.ClassID == XMESA_RENDERBUFFER) {
        XImage *ximage = xrb->ximage;

        if (!ximage) {
            /* this must be a pixmap/window renderbuffer */
            assert(xrb->pixmap);
            assert(xrb->map_ximage);
            if (xrb->map_ximage) {
                if (xrb->map_mode & GL_MAP_WRITE_BIT) {
                    /* put modified ximage data back into the pixmap/window */
                    int y2 = rb->Height - xrb->map_y - xrb->map_h;
                    GC gc = XCreateGC(xrb->Parent->display, xrb->pixmap, 0, NULL);

                    XPutImage(xrb->Parent->display,
                              xrb->pixmap,              /* dest */
                              gc,
                              xrb->map_ximage,          /* source */
                              0, 0,                     /* src x, y */
                              xrb->map_x, y2,           /* dest x, y */
                              xrb->map_w, xrb->map_h);  /* size */

                    XFreeGC(xrb->Parent->display, gc);
                }
                XMesaDestroyImage(xrb->map_ximage);
                xrb->map_ximage = NULL;
            }
        }

        xrb->map_mode = 0x0;

        return;
    }

    /* otherwise, this is an ordinary malloc-based renderbuffer */
    _swrast_unmap_soft_renderbuffer(ctx, rb);
}
Exemple #4
0
/*
 * Return the depth buffer associated with an XMesaBuffer.
 * Input:  b - the XMesa buffer handle
 * Output:  width, height - size of buffer in pixels
 *          bytesPerValue - bytes per depth value (2 or 4)
 *          buffer - pointer to depth buffer values
 * Return:  GL_TRUE or GL_FALSE to indicate success or failure.
 */
GLboolean XMesaGetDepthBuffer( XMesaBuffer b, GLint *width, GLint *height,
                               GLint *bytesPerValue, void **buffer )
{
   struct gl_renderbuffer *rb
      = b->mesa_buffer.Attachment[BUFFER_DEPTH].Renderbuffer;
   struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb);

   if (!xrb || !xrb->Base.Buffer) {
      *width = 0;
      *height = 0;
      *bytesPerValue = 0;
      *buffer = 0;
      return GL_FALSE;
   }
   else {
      *width = b->mesa_buffer.Width;
      *height = b->mesa_buffer.Height;
      *bytesPerValue = b->mesa_buffer.Visual.depthBits <= 16
         ? sizeof(GLushort) : sizeof(GLuint);
      *buffer = (void *) xrb->Base.Buffer;
      return GL_TRUE;
   }
}
Exemple #5
0
/**
 * Return pointer to line drawing function, or NULL if we should use a
 * swrast fallback.
 */
static swrast_tri_func
get_triangle_func(struct gl_context *ctx)
{
#if CHAN_BITS == 8
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   XMesaContext xmesa = XMESA_CONTEXT(ctx);
   const struct xmesa_renderbuffer *xrb;

#ifdef DEBUG
   triFuncName = NULL;
#endif

   /* trivial fallback tests */
   if ((ctx->DrawBuffer->_ColorDrawBufferIndexes[0] != BUFFER_BIT_FRONT_LEFT) &&
       (ctx->DrawBuffer->_ColorDrawBufferIndexes[0] != BUFFER_BIT_BACK_LEFT))
      return (swrast_tri_func) NULL;
   if (ctx->RenderMode != GL_RENDER)
      return (swrast_tri_func) NULL;
   if (ctx->Polygon.SmoothFlag)
      return (swrast_tri_func) NULL;
   if (ctx->Texture._EnabledUnits)
      return (swrast_tri_func) NULL;
   if (swrast->_RasterMask & MULTI_DRAW_BIT)
      return (swrast_tri_func) NULL;
   if (ctx->Polygon.CullFlag && 
       ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)
      return (swrast_tri_func) NULL;

   xrb = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]);

   if (xrb->ximage) {
      if (   ctx->Light.ShadeModel==GL_SMOOTH
          && swrast->_RasterMask==DEPTH_BIT
          && ctx->Depth.Func==GL_LESS
          && ctx->Depth.Mask==GL_TRUE
          && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS
          && ctx->Polygon.StippleFlag==GL_FALSE) {
         switch (xmesa->pixelformat) {
            case PF_Truecolor:
	       USE(smooth_TRUECOLOR_z_triangle);
            case PF_8A8B8G8R:
               USE(smooth_8A8B8G8R_z_triangle);
            case PF_8A8R8G8B:
               USE(smooth_8A8R8G8B_z_triangle);
            case PF_8R8G8B:
               USE(smooth_8R8G8B_z_triangle);
            case PF_8R8G8B24:
               USE(smooth_8R8G8B24_z_triangle);
            case PF_Dither_True:
               USE(smooth_TRUEDITHER_z_triangle);
            case PF_5R6G5B:
               USE(smooth_5R6G5B_z_triangle);
            case PF_Dither_5R6G5B:
               USE(smooth_DITHER_5R6G5B_z_triangle);
            default:
               return (swrast_tri_func) NULL;
         }
      }
      if (   ctx->Light.ShadeModel==GL_FLAT
          && swrast->_RasterMask==DEPTH_BIT
          && ctx->Depth.Func==GL_LESS
          && ctx->Depth.Mask==GL_TRUE
          && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS
          && ctx->Polygon.StippleFlag==GL_FALSE) {
         switch (xmesa->pixelformat) {
            case PF_Truecolor:
	       USE(flat_TRUECOLOR_z_triangle);
            case PF_8A8B8G8R:
               USE(flat_8A8B8G8R_z_triangle);
            case PF_8A8R8G8B:
               USE(flat_8A8R8G8B_z_triangle);
            case PF_8R8G8B:
               USE(flat_8R8G8B_z_triangle);
            case PF_8R8G8B24:
               USE(flat_8R8G8B24_z_triangle);
            case PF_Dither_True:
               USE(flat_TRUEDITHER_z_triangle);
            case PF_5R6G5B:
               USE(flat_5R6G5B_z_triangle);
            case PF_Dither_5R6G5B:
               USE(flat_DITHER_5R6G5B_z_triangle);
            default:
               return (swrast_tri_func) NULL;
         }
      }
      if (   swrast->_RasterMask==0   /* no depth test */
          && ctx->Light.ShadeModel==GL_SMOOTH
          && ctx->Polygon.StippleFlag==GL_FALSE) {
         switch (xmesa->pixelformat) {
            case PF_Truecolor:
	       USE(smooth_TRUECOLOR_triangle);
            case PF_8A8B8G8R:
               USE(smooth_8A8B8G8R_triangle);
            case PF_8A8R8G8B:
               USE(smooth_8A8R8G8B_triangle);
            case PF_8R8G8B:
               USE(smooth_8R8G8B_triangle);
            case PF_8R8G8B24:
               USE(smooth_8R8G8B24_triangle);
            case PF_Dither_True:
               USE(smooth_TRUEDITHER_triangle);
            case PF_5R6G5B:
               USE(smooth_5R6G5B_triangle);
            case PF_Dither_5R6G5B:
               USE(smooth_DITHER_5R6G5B_triangle);
            default:
               return (swrast_tri_func) NULL;
         }
      }

      if (   swrast->_RasterMask==0   /* no depth test */
          && ctx->Light.ShadeModel==GL_FLAT
          && ctx->Polygon.StippleFlag==GL_FALSE) {
         switch (xmesa->pixelformat) {
            case PF_Truecolor:
	       USE(flat_TRUECOLOR_triangle);
            case PF_Dither_True:
	       USE(flat_TRUEDITHER_triangle);
            case PF_8A8B8G8R:
               USE(flat_8A8B8G8R_triangle);
            case PF_8A8R8G8B:
               USE(flat_8A8R8G8B_triangle);
            case PF_8R8G8B:
               USE(flat_8R8G8B_triangle);
            case PF_8R8G8B24:
               USE(flat_8R8G8B24_triangle);
            case PF_5R6G5B:
               USE(flat_5R6G5B_triangle);
            case PF_Dither_5R6G5B:
               USE(flat_DITHER_5R6G5B_triangle);
            default:
               return (swrast_tri_func) NULL;
         }
      }
   }
#endif /* CHAN_BITS == 8 */

   return (swrast_tri_func) NULL;
}
Exemple #6
0
/**
 * Return pointer to line drawing function, or NULL if we should use a
 * swrast fallback.
 */
static swrast_line_func
get_line_func(struct gl_context *ctx)
{
#if CHAN_BITS == 8
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   XMesaContext xmesa = XMESA_CONTEXT(ctx);
   const struct xmesa_renderbuffer *xrb;

   if ((ctx->DrawBuffer->_ColorDrawBufferIndexes[0] != BUFFER_BIT_FRONT_LEFT) &&
       (ctx->DrawBuffer->_ColorDrawBufferIndexes[0] != BUFFER_BIT_BACK_LEFT))
      return (swrast_line_func) NULL;
   if (ctx->RenderMode != GL_RENDER)      return (swrast_line_func) NULL;
   if (ctx->Line.SmoothFlag)              return (swrast_line_func) NULL;
   if (ctx->Texture._MaxEnabledTexImageUnit != -1)        return (swrast_line_func) NULL;
   if (ctx->Light.ShadeModel != GL_FLAT)  return (swrast_line_func) NULL;
   if (ctx->Line.StippleFlag)             return (swrast_line_func) NULL;
   if (swrast->_RasterMask & MULTI_DRAW_BIT) return (swrast_line_func) NULL;

   xrb = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]);

   if (xrb->ximage
       && swrast->_RasterMask==DEPTH_BIT
       && ctx->Depth.Func==GL_LESS
       && ctx->Depth.Mask==GL_TRUE
       && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS
       && ctx->Line.Width==1.0F) {
      switch (xmesa->pixelformat) {
         case PF_Truecolor:
            return flat_TRUECOLOR_z_line;
         case PF_8A8B8G8R:
            return flat_8A8B8G8R_z_line;
         case PF_8A8R8G8B:
            return flat_8A8R8G8B_z_line;
         case PF_8R8G8B:
            return flat_8R8G8B_z_line;
         case PF_8R8G8B24:
            return flat_8R8G8B24_z_line;
         case PF_5R6G5B:
            return flat_5R6G5B_z_line;
         case PF_Dither_5R6G5B:
            return flat_DITHER_5R6G5B_z_line;
         default:
            return (swrast_line_func)NULL;
      }
   }
   if (xrb->ximage
       && swrast->_RasterMask==0
       && ctx->Line.Width==1.0F) {
      switch (xmesa->pixelformat) {
         case PF_Truecolor:
            return flat_TRUECOLOR_line;
         case PF_8A8B8G8R:
            return flat_8A8B8G8R_line;
         case PF_8A8R8G8B:
            return flat_8A8R8G8B_line;
         case PF_8R8G8B:
            return flat_8R8G8B_line;
         case PF_8R8G8B24:
            return flat_8R8G8B24_line;
         case PF_5R6G5B:
            return flat_5R6G5B_line;
         case PF_Dither_5R6G5B:
            return flat_DITHER_5R6G5B_line;
	 default:
	    return (swrast_line_func)NULL;
      }
   }

   if (ctx->DrawBuffer->_NumColorDrawBuffers == 1
       && ctx->DrawBuffer->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT
       && swrast->_RasterMask == LOGIC_OP_BIT
       && ctx->Color.LogicOp == GL_XOR
       && !ctx->Line.StippleFlag
       && !ctx->Line.SmoothFlag) {
      return xor_line;
   }

#endif /* CHAN_BITS == 8 */
   return (swrast_line_func) NULL;
}
Exemple #7
0
/**
 * Called via ctx->Driver.MapRenderbuffer()
 */
void
xmesa_MapRenderbuffer(struct gl_context *ctx,
                      struct gl_renderbuffer *rb,
                      GLuint x, GLuint y, GLuint w, GLuint h,
                      GLbitfield mode,
                      GLubyte **mapOut, GLint *rowStrideOut)
{
    struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb);

    if (xrb->Base.Base.ClassID == XMESA_RENDERBUFFER) {
        XImage *ximage = xrb->ximage;

        assert(!xrb->map_mode); /* only a single mapping allowed */

        xrb->map_mode = mode;
        xrb->map_x = x;
        xrb->map_y = y;
        xrb->map_w = w;
        xrb->map_h = h;

        if (ximage) {
            int y2 = rb->Height - y - 1;

            *mapOut = (GLubyte *) ximage->data
                      + y2 * ximage->bytes_per_line
                      + x * ximage->bits_per_pixel / 8;
        }
        else {
            /* this must be a pixmap/window renderbuffer */
            int (*old_handler)(XMesaDisplay *, XErrorEvent *);
            int y2 = rb->Height - y - h;

            assert(xrb->pixmap);

            /* Install error handler for XGetImage() in case the the window
             * isn't mapped.  If we fail we'll create a temporary XImage.
             */
            mesaXErrorFlag = 0;
            old_handler = XSetErrorHandler(mesaHandleXError);

            /* read pixel data out of the pixmap/window into an XImage */
            ximage = XGetImage(xrb->Parent->display,
                               xrb->pixmap, x, y2, w, h,
                               AllPlanes, ZPixmap);

            XSetErrorHandler(old_handler);

            if (mesaXErrorFlag) {
                /* create new, temporary XImage */
                int bytes_per_line =
                    _mesa_format_row_stride(xrb->Base.Base.Format,
                                            xrb->Base.Base.Width);
                char *image = (char *) malloc(bytes_per_line *
                                              xrb->Base.Base.Height);
                ximage = XCreateImage(xrb->Parent->display,
                                      xrb->Parent->xm_visual->visinfo->visual,
                                      xrb->Parent->xm_visual->visinfo->depth,
                                      ZPixmap, /* format */
                                      0, /* offset */
                                      image, /* data */
                                      xrb->Base.Base.Width,
                                      xrb->Base.Base.Height,
                                      8, /* pad */
                                      bytes_per_line);
            }

            if (!ximage) {
                *mapOut = NULL;
                *rowStrideOut = 0;
                return;
            }

            xrb->map_ximage = ximage;

            /* the first row of the OpenGL image is last row of the XImage */
            *mapOut = (GLubyte *) ximage->data
                      + (h - 1) * ximage->bytes_per_line;
        }

        /* We return a negative stride here since XImage data is upside down
         * with respect to OpenGL images.
         */
        *rowStrideOut = -ximage->bytes_per_line;
        return;
    }

    /* otherwise, this is an ordinary malloc-based renderbuffer */
    _swrast_map_soft_renderbuffer(ctx, rb, x, y, w, h, mode,
                                  mapOut, rowStrideOut);
}
Exemple #8
0
/**
 * Called via ctx->Driver.MapRenderbuffer()
 */
void
xmesa_MapRenderbuffer(struct gl_context *ctx,
                      struct gl_renderbuffer *rb,
                      GLuint x, GLuint y, GLuint w, GLuint h,
                      GLbitfield mode,
                      GLubyte **mapOut, GLint *rowStrideOut)
{
   struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb);

   if (xrb->Base.Base.ClassID == XMESA_RENDERBUFFER) {
      XImage *ximage = xrb->ximage;

      assert(!xrb->map_mode); /* only a single mapping allowed */

      xrb->map_mode = mode;
      xrb->map_x = x;
      xrb->map_y = y;
      xrb->map_w = w;
      xrb->map_h = h;

      if (ximage) {
         int y2 = rb->Height - y - 1;

         *mapOut = (GLubyte *) ximage->data
            + y2 * ximage->bytes_per_line
            + x * ximage->bits_per_pixel / 8;
      }
      else {
         /* this must be a pixmap/window renderbuffer */
         int y2 = rb->Height - y - h;

         assert(xrb->pixmap);

         /* read pixel data out of the pixmap/window into an XImage */
         ximage = XGetImage(xrb->Parent->display,
                            xrb->pixmap, x, y2, w, h,
                            AllPlanes, ZPixmap);
         if (!ximage) {
            *mapOut = NULL;
            *rowStrideOut = 0;
            return;
         }

         xrb->map_ximage = ximage;

         /* the first row of the OpenGL image is last row of the XImage */
         *mapOut = (GLubyte *) ximage->data
            + (h - 1) * ximage->bytes_per_line;
      }

      /* We return a negative stride here since XImage data is upside down
       * with respect to OpenGL images.
       */
      *rowStrideOut = -ximage->bytes_per_line;
      return;
   }

   /* otherwise, this is an ordinary malloc-based renderbuffer */
   _swrast_map_soft_renderbuffer(ctx, rb, x, y, w, h, mode,
                                 mapOut, rowStrideOut);
}
Exemple #9
0
PUBLIC void
XMesaBindTexImage(XMesaDisplay *dpy, XMesaBuffer drawable, int buffer,
                  const int *attrib_list)
{
#if 0
   GET_CURRENT_CONTEXT(ctx);
   const GLuint unit = ctx->Texture.CurrentUnit;
   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
   struct gl_texture_object *texObj;
#endif
   struct gl_renderbuffer *rb;
   struct xmesa_renderbuffer *xrb;
   GLint b;
   XMesaImage *img = NULL;
   GLboolean freeImg = GL_FALSE;

   b = xbuffer_to_renderbuffer(buffer);
   if (b < 0)
      return;

   if (drawable->TextureFormat == GLX_TEXTURE_FORMAT_NONE_EXT)
      return; /* BadMatch error */

   rb = drawable->mesa_buffer.Attachment[b].Renderbuffer;
   if (!rb) {
      /* invalid buffer */
      return;
   }
   xrb = xmesa_renderbuffer(rb);

#if 0
   switch (drawable->TextureTarget) {
   case GLX_TEXTURE_1D_EXT:
      texObj = texUnit->CurrentTex[TEXTURE_1D_INDEX];
      break;
   case GLX_TEXTURE_2D_EXT:
      texObj = texUnit->CurrentTex[TEXTURE_2D_INDEX];
      break;
   case GLX_TEXTURE_RECTANGLE_EXT:
      texObj = texUnit->CurrentTex[TEXTURE_RECT_INDEX];
      break;
   default:
      return; /* BadMatch error */
   }
#endif

   /*
    * The following is a quick and simple way to implement
    * BindTexImage.  The better way is to write some new FetchTexel()
    * functions which would extract texels from XImages.  We'd still
    * need to use GetImage when texturing from a Pixmap (front buffer)
    * but texturing from a back buffer (XImage) would avoid an image
    * copy.
    */

   /* get XImage */
   if (xrb->pixmap) {
      img = XMesaGetImage(dpy, xrb->pixmap, 0, 0, rb->Width, rb->Height, ~0L,
			  ZPixmap);
      freeImg = GL_TRUE;
   }
   else if (xrb->ximage) {
      img = xrb->ximage;
   }

   /* store the XImage as a new texture image */
   if (img) {
      GLenum format, type, intFormat;
      if (img->bits_per_pixel == 32) {
         format = GL_BGRA;
         type = GL_UNSIGNED_BYTE;
         intFormat = GL_RGBA;
      }
      else if (img->bits_per_pixel == 24) {
         format = GL_BGR;
         type = GL_UNSIGNED_BYTE;
         intFormat = GL_RGB;
      }
      else if (img->bits_per_pixel == 16) {
         format = GL_BGR;
         type = GL_UNSIGNED_SHORT_5_6_5;
         intFormat = GL_RGB;
      }
      else {
         _mesa_problem(NULL, "Unexpected XImage format in XMesaBindTexImage");
         return;
      }
      if (drawable->TextureFormat == GLX_TEXTURE_FORMAT_RGBA_EXT) {
         intFormat = GL_RGBA;
      }
      else if (drawable->TextureFormat == GLX_TEXTURE_FORMAT_RGB_EXT) {
         intFormat = GL_RGB;
      }

      _mesa_TexImage2D(GL_TEXTURE_2D, 0, intFormat, rb->Width, rb->Height, 0,
                       format, type, img->data);

      if (freeImg) {
	 XMesaDestroyImage(img);
      }
   }
}