glamor: Create FBOs for pixmaps.
This commit is contained in:
		
							parent
							
								
									f92d1478e9
								
							
						
					
					
						commit
						519103565c
					
				| 
						 | 
				
			
			@ -40,6 +40,8 @@
 | 
			
		|||
 | 
			
		||||
static int glamor_screen_private_key_index;
 | 
			
		||||
DevPrivateKey glamor_screen_private_key = &glamor_screen_private_key_index;
 | 
			
		||||
static int glamor_pixmap_private_key_index;
 | 
			
		||||
DevPrivateKey glamor_pixmap_private_key = &glamor_pixmap_private_key_index;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * glamor_get_drawable_pixmap() returns a backing pixmap for a given drawable.
 | 
			
		||||
| 
						 | 
				
			
			@ -63,9 +65,57 @@ glamor_get_drawable_pixmap(DrawablePtr drawable)
 | 
			
		|||
 | 
			
		||||
static PixmapPtr
 | 
			
		||||
glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 | 
			
		||||
		     unsigned int usage_hint)
 | 
			
		||||
		     unsigned int usage)
 | 
			
		||||
{
 | 
			
		||||
    return fbCreatePixmap(screen, w, h, depth, usage_hint);
 | 
			
		||||
    PixmapPtr pixmap;
 | 
			
		||||
    glamor_pixmap_private *pixmap_priv;
 | 
			
		||||
    GLenum format;
 | 
			
		||||
 | 
			
		||||
    if (w > 32767 || h > 32767)
 | 
			
		||||
	return NullPixmap;
 | 
			
		||||
 | 
			
		||||
    pixmap = fbCreatePixmap (screen, 0, 0, depth, usage);
 | 
			
		||||
    pixmap_priv = glamor_get_pixmap_private(pixmap);
 | 
			
		||||
 | 
			
		||||
    if (w == 0 || h == 0)
 | 
			
		||||
	return pixmap;
 | 
			
		||||
 | 
			
		||||
    /* We should probably take advantage of ARB_fbo's allowance of GL_ALPHA.
 | 
			
		||||
     * FBOs, which EXT_fbo forgot to do.
 | 
			
		||||
     */
 | 
			
		||||
    switch (depth) {
 | 
			
		||||
    case 24:
 | 
			
		||||
	format = GL_RGB;
 | 
			
		||||
	break;
 | 
			
		||||
    default:
 | 
			
		||||
	format = GL_RGBA;
 | 
			
		||||
	break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Create the texture used to store the pixmap's data. */
 | 
			
		||||
    glGenTextures(1, &pixmap_priv->tex);
 | 
			
		||||
    glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
 | 
			
		||||
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 | 
			
		||||
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 | 
			
		||||
    glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
 | 
			
		||||
		 format, GL_UNSIGNED_BYTE, NULL);
 | 
			
		||||
 | 
			
		||||
    /* Create a framebuffer object wrapping the texture so that we can render
 | 
			
		||||
     * to it.
 | 
			
		||||
     */
 | 
			
		||||
    glGenFramebuffersEXT(1, &pixmap_priv->fb);
 | 
			
		||||
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
 | 
			
		||||
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
 | 
			
		||||
			      GL_COLOR_ATTACHMENT0_EXT,
 | 
			
		||||
			      GL_TEXTURE_2D,
 | 
			
		||||
			      pixmap_priv->tex,
 | 
			
		||||
			      0);
 | 
			
		||||
 | 
			
		||||
    screen->ModifyPixmapHeader(pixmap, w, h, 0, 0,
 | 
			
		||||
			       (w * pixmap->drawable.bitsPerPixel + 7) / 8,
 | 
			
		||||
			       NULL);
 | 
			
		||||
 | 
			
		||||
    return pixmap;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Bool
 | 
			
		||||
| 
						 | 
				
			
			@ -96,9 +146,19 @@ glamor_init(ScreenPtr screen)
 | 
			
		|||
	return FALSE;
 | 
			
		||||
 | 
			
		||||
    dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, glamor_priv);
 | 
			
		||||
    if (!dixRequestPrivate(glamor_pixmap_private_key,
 | 
			
		||||
			   sizeof(glamor_pixmap_private))) {
 | 
			
		||||
	LogMessage(X_WARNING,
 | 
			
		||||
		   "glamor%d: Failed to allocate pixmap private\n",
 | 
			
		||||
		   screen->myNum);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    glewInit();
 | 
			
		||||
 | 
			
		||||
    if (!GLEW_EXT_framebuffer_object) {
 | 
			
		||||
	ErrorF("GL_EXT_framebuffer_object required\n");
 | 
			
		||||
	goto fail;
 | 
			
		||||
    }
 | 
			
		||||
    if (!GLEW_ARB_shader_objects) {
 | 
			
		||||
	ErrorF("GL_ARB_shader_objects required\n");
 | 
			
		||||
	goto fail;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,17 +42,28 @@
 | 
			
		|||
Bool
 | 
			
		||||
glamor_set_destination_pixmap(PixmapPtr pixmap)
 | 
			
		||||
{
 | 
			
		||||
    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
 | 
			
		||||
 | 
			
		||||
    if (pixmap_priv == NULL) {
 | 
			
		||||
	ErrorF("no pixmap priv?");
 | 
			
		||||
	return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (pixmap_priv->fb == 0) {
 | 
			
		||||
	ScreenPtr screen = pixmap->drawable.pScreen;
 | 
			
		||||
	PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
 | 
			
		||||
 | 
			
		||||
	if (pixmap != screen_pixmap) {
 | 
			
		||||
	ErrorF("stubbed drawing to non-screen pixmap\n");
 | 
			
		||||
	    ErrorF("No FBO\n");
 | 
			
		||||
	    return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
 | 
			
		||||
 | 
			
		||||
    glViewport(0, 0,
 | 
			
		||||
	       screen_pixmap->drawable.width,
 | 
			
		||||
	       screen_pixmap->drawable.height);
 | 
			
		||||
	       pixmap->drawable.width,
 | 
			
		||||
	       pixmap->drawable.height);
 | 
			
		||||
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -75,10 +86,18 @@ void
 | 
			
		|||
glamor_set_transform_for_pixmap(PixmapPtr pixmap,
 | 
			
		||||
				glamor_transform_uniforms *uniform_locations)
 | 
			
		||||
{
 | 
			
		||||
    ScreenPtr screen = pixmap->drawable.pScreen;
 | 
			
		||||
    PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
 | 
			
		||||
 | 
			
		||||
    glUniform1fARB(uniform_locations->x_bias, -pixmap->drawable.width / 2.0f);
 | 
			
		||||
    glUniform1fARB(uniform_locations->x_scale, 2.0f / pixmap->drawable.width);
 | 
			
		||||
    glUniform1fARB(uniform_locations->y_bias, -pixmap->drawable.height / 2.0f);
 | 
			
		||||
    glUniform1fARB(uniform_locations->y_scale, -2.0f / pixmap->drawable.height);
 | 
			
		||||
    if (pixmap == screen_pixmap)
 | 
			
		||||
	glUniform1fARB(uniform_locations->y_scale,
 | 
			
		||||
		       -2.0f / pixmap->drawable.height);
 | 
			
		||||
    else
 | 
			
		||||
	glUniform1fARB(uniform_locations->y_scale,
 | 
			
		||||
		       2.0f / pixmap->drawable.height);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GLint
 | 
			
		||||
| 
						 | 
				
			
			@ -176,28 +195,14 @@ static void
 | 
			
		|||
glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 | 
			
		||||
		 int w, int h, int leftPad, int format, char *bits)
 | 
			
		||||
{
 | 
			
		||||
    ScreenPtr screen = drawable->pScreen;
 | 
			
		||||
    PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
 | 
			
		||||
    PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
 | 
			
		||||
 | 
			
		||||
    if (screen_pixmap != dest_pixmap) {
 | 
			
		||||
	fbPutImage(drawable, gc, depth, x, y, w, h, leftPad, format, bits);
 | 
			
		||||
    } else {
 | 
			
		||||
    ErrorF("stub put_image\n");
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 | 
			
		||||
		 DDXPointPtr points, int *widths, int n, int sorted)
 | 
			
		||||
{
 | 
			
		||||
    ScreenPtr screen = drawable->pScreen;
 | 
			
		||||
    PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
 | 
			
		||||
    PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
 | 
			
		||||
 | 
			
		||||
    if (screen_pixmap != dest_pixmap) {
 | 
			
		||||
	fbSetSpans(drawable, gc, src, points, widths, n, sorted);
 | 
			
		||||
    } else {
 | 
			
		||||
    GLenum format, type;
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -224,7 +229,6 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 | 
			
		|||
	src += PixmapBytePad(widths[i], drawable->depth);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * glamor_poly_lines() checks if it can accelerate the lines as a group of
 | 
			
		||||
| 
						 | 
				
			
			@ -235,9 +239,6 @@ static void
 | 
			
		|||
glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
 | 
			
		||||
		  DDXPointPtr points)
 | 
			
		||||
{
 | 
			
		||||
    ScreenPtr screen = drawable->pScreen;
 | 
			
		||||
    PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
 | 
			
		||||
    PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
 | 
			
		||||
    xRectangle *rects;
 | 
			
		||||
    int x1, x2, y1, y2;
 | 
			
		||||
    int i;
 | 
			
		||||
| 
						 | 
				
			
			@ -245,9 +246,6 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
 | 
			
		|||
    /* Don't try to do wide lines or non-solid fill style. */
 | 
			
		||||
    if (gc->lineWidth != 0 || gc->lineStyle != LineSolid ||
 | 
			
		||||
	gc->fillStyle != FillSolid) {
 | 
			
		||||
	if (dest_pixmap != screen_pixmap)
 | 
			
		||||
	    fbPolyLine(drawable, gc, mode, n, points);
 | 
			
		||||
	else
 | 
			
		||||
	ErrorF("stub poly_line\n");
 | 
			
		||||
	return;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -267,9 +265,6 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
 | 
			
		|||
 | 
			
		||||
	if (x1 != x2 && y1 != y2) {
 | 
			
		||||
	    xfree(rects);
 | 
			
		||||
	    if (dest_pixmap != screen_pixmap)
 | 
			
		||||
		fbPolyLine(drawable, gc, mode, n, points);
 | 
			
		||||
	    else
 | 
			
		||||
	    ErrorF("stub poly_line\n");
 | 
			
		||||
	    return;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,14 +44,6 @@ glamor_fill_spans(DrawablePtr drawable,
 | 
			
		|||
    int extentX1, extentX2, extentY1, extentY2;
 | 
			
		||||
    int fullX1, fullX2, fullY1;
 | 
			
		||||
    int partX1, partX2;
 | 
			
		||||
    ScreenPtr screen = drawable->pScreen;
 | 
			
		||||
    PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
 | 
			
		||||
    PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
 | 
			
		||||
 | 
			
		||||
    if (dest_pixmap != screen_pixmap) {
 | 
			
		||||
	fbFillSpans(drawable, gc, n, points, widths, sorted);
 | 
			
		||||
	return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    extents = REGION_EXTENTS(gc->pScreen, clip);
 | 
			
		||||
    extentX1 = extents->x1;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,16 +39,10 @@ glamor_get_spans(DrawablePtr drawable,
 | 
			
		|||
		 int count,
 | 
			
		||||
		 char *dst)
 | 
			
		||||
{
 | 
			
		||||
    ScreenPtr screen = drawable->pScreen;
 | 
			
		||||
    PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
 | 
			
		||||
    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
 | 
			
		||||
 | 
			
		||||
    if (screen_pixmap != pixmap) {
 | 
			
		||||
	fbGetSpans(drawable, wmax, points, widths, count, dst);
 | 
			
		||||
	return;
 | 
			
		||||
    } else {
 | 
			
		||||
    GLenum format, type;
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    switch (drawable->depth) {
 | 
			
		||||
    case 24:
 | 
			
		||||
    case 32:
 | 
			
		||||
| 
						 | 
				
			
			@ -59,8 +53,12 @@ glamor_get_spans(DrawablePtr drawable,
 | 
			
		|||
	ErrorF("Unknown getspans depth %d\n", drawable->depth);
 | 
			
		||||
	return;
 | 
			
		||||
    }
 | 
			
		||||
	if (!glamor_set_destination_pixmap(pixmap))
 | 
			
		||||
 | 
			
		||||
    if (!glamor_set_destination_pixmap(pixmap)) {
 | 
			
		||||
	fbGetSpans(drawable, wmax, points, widths, count, dst);
 | 
			
		||||
	return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < count; i++) {
 | 
			
		||||
	glReadPixels(points[i].x - pixmap->screen_x,
 | 
			
		||||
		     points[i].y - pixmap->screen_y,
 | 
			
		||||
| 
						 | 
				
			
			@ -71,4 +69,3 @@ glamor_get_spans(DrawablePtr drawable,
 | 
			
		|||
	dst += PixmapBytePad(widths[i], drawable->depth);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -50,13 +50,24 @@ typedef struct glamor_screen_private {
 | 
			
		|||
    glamor_transform_uniforms solid_transform;
 | 
			
		||||
} glamor_screen_private;
 | 
			
		||||
 | 
			
		||||
typedef struct glamor_pixmap_private {
 | 
			
		||||
    GLuint tex;
 | 
			
		||||
    GLuint fb;
 | 
			
		||||
} glamor_pixmap_private;
 | 
			
		||||
 | 
			
		||||
extern DevPrivateKey glamor_screen_private_key;
 | 
			
		||||
extern DevPrivateKey glamor_pixmap_private_key;
 | 
			
		||||
static inline glamor_screen_private *
 | 
			
		||||
glamor_get_screen_private(ScreenPtr screen)
 | 
			
		||||
{
 | 
			
		||||
    return (glamor_screen_private *)dixLookupPrivate(&screen->devPrivates,
 | 
			
		||||
						     glamor_screen_private_key);
 | 
			
		||||
}
 | 
			
		||||
static inline glamor_pixmap_private *
 | 
			
		||||
glamor_get_pixmap_private(PixmapPtr pixmap)
 | 
			
		||||
{
 | 
			
		||||
    return dixLookupPrivate(&pixmap->devPrivates, glamor_pixmap_private_key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* glamor.c */
 | 
			
		||||
PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue