glamor: Add prepare/finishaccess code based on UXA.
This commit is contained in:
		
							parent
							
								
									f17473cdd5
								
							
						
					
					
						commit
						c4343dfa0a
					
				|  | @ -177,6 +177,10 @@ glamor_init(ScreenPtr screen) | ||||||
| 	ErrorF("GL_ARB_vertex_shader required\n"); | 	ErrorF("GL_ARB_vertex_shader required\n"); | ||||||
| 	goto fail; | 	goto fail; | ||||||
|     } |     } | ||||||
|  |     if (!GLEW_ARB_pixel_buffer_object) { | ||||||
|  | 	ErrorF("GL_ARB_pixel_buffer_object required\n"); | ||||||
|  | 	goto fail; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     if (!RegisterBlockAndWakeupHandlers(glamor_block_handler, |     if (!RegisterBlockAndWakeupHandlers(glamor_block_handler, | ||||||
| 					glamor_wakeup_handler, | 					glamor_wakeup_handler, | ||||||
|  | @ -199,6 +203,12 @@ glamor_init(ScreenPtr screen) | ||||||
|     glamor_priv->saved_get_image = screen->GetImage; |     glamor_priv->saved_get_image = screen->GetImage; | ||||||
|     screen->GetImage = miGetImage; |     screen->GetImage = miGetImage; | ||||||
| 
 | 
 | ||||||
|  |     glamor_priv->saved_change_window_attributes = screen->ChangeWindowAttributes; | ||||||
|  |     screen->ChangeWindowAttributes = glamor_change_window_attributes; | ||||||
|  | 
 | ||||||
|  |     glamor_priv->saved_bitmap_to_region = screen->BitmapToRegion; | ||||||
|  |     screen->BitmapToRegion = glamor_bitmap_to_region; | ||||||
|  | 
 | ||||||
| #ifdef RENDER | #ifdef RENDER | ||||||
|     glamor_priv->saved_composite = ps->Composite; |     glamor_priv->saved_composite = ps->Composite; | ||||||
|     ps->Composite = glamor_composite; |     ps->Composite = glamor_composite; | ||||||
|  | @ -231,6 +241,8 @@ glamor_fini(ScreenPtr screen) | ||||||
|     screen->CreatePixmap = glamor_priv->saved_create_pixmap; |     screen->CreatePixmap = glamor_priv->saved_create_pixmap; | ||||||
|     screen->DestroyPixmap = glamor_priv->saved_destroy_pixmap; |     screen->DestroyPixmap = glamor_priv->saved_destroy_pixmap; | ||||||
|     screen->GetSpans = glamor_priv->saved_get_spans; |     screen->GetSpans = glamor_priv->saved_get_spans; | ||||||
|  |     screen->ChangeWindowAttributes = glamor_priv->saved_change_window_attributes; | ||||||
|  |     screen->BitmapToRegion = glamor_priv->saved_bitmap_to_region; | ||||||
| #ifdef RENDER | #ifdef RENDER | ||||||
|     ps->Composite = glamor_priv->saved_composite; |     ps->Composite = glamor_priv->saved_composite; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -260,6 +260,129 @@ glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel, | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | Bool | ||||||
|  | glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) | ||||||
|  | { | ||||||
|  |     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); | ||||||
|  |     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); | ||||||
|  |     unsigned int stride; | ||||||
|  |     GLenum format, type; | ||||||
|  | 
 | ||||||
|  |     if (pixmap_priv == NULL) | ||||||
|  | 	return TRUE; | ||||||
|  | 
 | ||||||
|  |     if (pixmap_priv->fb == 0) { | ||||||
|  | 	ScreenPtr screen = pixmap->drawable.pScreen; | ||||||
|  | 	PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); | ||||||
|  | 
 | ||||||
|  | 	if (pixmap != screen_pixmap) | ||||||
|  | 	    return TRUE; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     stride = PixmapBytePad(drawable->width, drawable->depth); | ||||||
|  | 
 | ||||||
|  |     switch (drawable->depth) { | ||||||
|  |     case 1: | ||||||
|  | 	format = GL_COLOR_INDEX; | ||||||
|  | 	type = GL_BITMAP; | ||||||
|  | 	break; | ||||||
|  |     case 8: | ||||||
|  | 	format = GL_ALPHA; | ||||||
|  | 	type = GL_UNSIGNED_BYTE; | ||||||
|  | 	break; | ||||||
|  |     case 24: | ||||||
|  | 	format = GL_RGB; | ||||||
|  | 	type = GL_UNSIGNED_BYTE; | ||||||
|  | 	break; | ||||||
|  |     case 32: | ||||||
|  | 	format = GL_BGRA; | ||||||
|  | 	type = GL_UNSIGNED_INT_8_8_8_8_REV; | ||||||
|  | 	break; | ||||||
|  |     default: | ||||||
|  | 	ErrorF("Unknown prepareaccess depth %d\n", drawable->depth); | ||||||
|  | 	return FALSE; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); | ||||||
|  |     glGenBuffersARB(1, &pixmap_priv->pbo); | ||||||
|  |     glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo); | ||||||
|  |     glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT, stride * drawable->height, | ||||||
|  | 		    NULL, GL_DYNAMIC_DRAW_ARB); | ||||||
|  |     glPixelStorei(GL_PACK_ALIGNMENT, 1); | ||||||
|  |     glPixelStorei(GL_PACK_ROW_LENGTH, stride * 8 / | ||||||
|  | 		  pixmap->drawable.bitsPerPixel); | ||||||
|  | 
 | ||||||
|  |     glReadPixels(0, 0, | ||||||
|  | 		 pixmap->drawable.width, pixmap->drawable.height, | ||||||
|  | 		 format, type, 0); | ||||||
|  | 
 | ||||||
|  |     pixmap->devPrivate.ptr = glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, | ||||||
|  | 					    GL_READ_WRITE_ARB); | ||||||
|  | 
 | ||||||
|  |     return TRUE; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | glamor_finish_access(DrawablePtr drawable) | ||||||
|  | { | ||||||
|  |     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); | ||||||
|  |     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); | ||||||
|  |     unsigned int stride; | ||||||
|  |     GLenum format, type; | ||||||
|  | 
 | ||||||
|  |     if (pixmap_priv == NULL) | ||||||
|  | 	return; | ||||||
|  | 
 | ||||||
|  |     if (pixmap_priv->fb == 0) { | ||||||
|  | 	ScreenPtr screen = pixmap->drawable.pScreen; | ||||||
|  | 	PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); | ||||||
|  | 
 | ||||||
|  | 	if (pixmap != screen_pixmap) | ||||||
|  | 	    return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0); | ||||||
|  |     glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pixmap_priv->pbo); | ||||||
|  |     glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT); | ||||||
|  |     pixmap->devPrivate.ptr = NULL; | ||||||
|  | 
 | ||||||
|  |     stride = PixmapBytePad(drawable->width, drawable->depth); | ||||||
|  | 
 | ||||||
|  |     switch (drawable->depth) { | ||||||
|  |     case 1: | ||||||
|  | 	format = GL_COLOR_INDEX; | ||||||
|  | 	type = GL_BITMAP; | ||||||
|  | 	break; | ||||||
|  |     case 8: | ||||||
|  | 	format = GL_ALPHA; | ||||||
|  | 	type = GL_UNSIGNED_BYTE; | ||||||
|  | 	break; | ||||||
|  |     case 24: | ||||||
|  | 	format = GL_RGB; | ||||||
|  | 	type = GL_UNSIGNED_BYTE; | ||||||
|  | 	break; | ||||||
|  |     case 32: | ||||||
|  | 	format = GL_BGRA; | ||||||
|  | 	type = GL_UNSIGNED_INT_8_8_8_8_REV; | ||||||
|  | 	break; | ||||||
|  |     default: | ||||||
|  | 	ErrorF("Unknown finishaccess depth %d\n", drawable->depth); | ||||||
|  | 	return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); | ||||||
|  |     glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pixmap_priv->pbo); | ||||||
|  |     glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | ||||||
|  |     glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8 / | ||||||
|  | 		  pixmap->drawable.bitsPerPixel); | ||||||
|  | 
 | ||||||
|  |     glRasterPos2i(0, 0); | ||||||
|  |     glDrawPixels(pixmap->drawable.width, pixmap->drawable.height, | ||||||
|  | 		 format, type, 0); | ||||||
|  |     glDeleteBuffersARB(1, &pixmap_priv->pbo); | ||||||
|  |     glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void | void | ||||||
| glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple, | glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple, | ||||||
| 	       int x, int y, int width, int height, | 	       int x, int y, int width, int height, | ||||||
|  | @ -364,13 +487,78 @@ GCOps glamor_gc_ops = { | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * exaValidateGC() sets the ops to EXA's implementations, which may be |  * uxa_validate_gc() sets the ops to glamor's implementations, which may be | ||||||
|  * accelerated or may sync the card and fall back to fb. |  * accelerated or may sync the card and fall back to fb. | ||||||
|  */ |  */ | ||||||
| static void | static void | ||||||
| glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable) | glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable) | ||||||
| { | { | ||||||
|     fbValidateGC(gc, changes, drawable); |     /* fbValidateGC will do direct access to pixmaps if the tiling has changed.
 | ||||||
|  |      * Preempt fbValidateGC by doing its work and masking the change out, so | ||||||
|  |      * that we can do the Prepare/finish_access. | ||||||
|  |      */ | ||||||
|  | #ifdef FB_24_32BIT | ||||||
|  |     if ((changes & GCTile) && fbGetRotatedPixmap(gc)) { | ||||||
|  | 	gc->pScreen->DestroyPixmap(fbGetRotatedPixmap(gc)); | ||||||
|  | 	fbGetRotatedPixmap(gc) = 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (gc->fillStyle == FillTiled) { | ||||||
|  | 	PixmapPtr old_tile, new_tile; | ||||||
|  | 
 | ||||||
|  | 	old_tile = gc->tile.pixmap; | ||||||
|  | 	if (old_tile->drawable.bitsPerPixel != drawable->bitsPerPixel) { | ||||||
|  | 	    new_tile = fbGetRotatedPixmap(gc); | ||||||
|  | 	    if (!new_tile || | ||||||
|  | 		new_tile ->drawable.bitsPerPixel != drawable->bitsPerPixel) | ||||||
|  | 	    { | ||||||
|  | 		if (new_tile) | ||||||
|  | 		    gc->pScreen->DestroyPixmap(new_tile); | ||||||
|  | 		/* fb24_32ReformatTile will do direct access of a newly-
 | ||||||
|  | 		 * allocated pixmap. | ||||||
|  | 		 */ | ||||||
|  | 		if (glamor_prepare_access(&old_tile->drawable, | ||||||
|  | 					  GLAMOR_ACCESS_RO)) { | ||||||
|  | 		    new_tile = fb24_32ReformatTile(old_tile, | ||||||
|  | 						   drawable->bitsPerPixel); | ||||||
|  | 		    glamor_finish_access(&old_tile->drawable); | ||||||
|  | 		} | ||||||
|  | 	    } | ||||||
|  | 	    if (new_tile) { | ||||||
|  | 		fbGetRotatedPixmap(gc) = old_tile; | ||||||
|  | 		gc->tile.pixmap = new_tile; | ||||||
|  | 		changes |= GCTile; | ||||||
|  | 	    } | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  | #endif | ||||||
|  |     if (changes & GCTile) { | ||||||
|  | 	if (!gc->tileIsPixel && FbEvenTile(gc->tile.pixmap->drawable.width * | ||||||
|  | 					   drawable->bitsPerPixel)) | ||||||
|  | 	{ | ||||||
|  | 	    if (glamor_prepare_access(&gc->tile.pixmap->drawable, | ||||||
|  | 				      GLAMOR_ACCESS_RW)) { | ||||||
|  | 		fbPadPixmap(gc->tile.pixmap); | ||||||
|  | 		glamor_finish_access(&gc->tile.pixmap->drawable); | ||||||
|  | 	    } | ||||||
|  | 	} | ||||||
|  | 	/* Mask out the GCTile change notification, now that we've done FB's
 | ||||||
|  | 	 * job for it. | ||||||
|  | 	 */ | ||||||
|  | 	changes &= ~GCTile; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (changes & GCStipple && gc->stipple) { | ||||||
|  | 	/* We can't inline stipple handling like we do for GCTile because
 | ||||||
|  | 	 * it sets fbgc privates. | ||||||
|  | 	 */ | ||||||
|  | 	if (glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RW)) { | ||||||
|  | 	    fbValidateGC(gc, changes, drawable); | ||||||
|  | 	    glamor_finish_access(&gc->stipple->drawable); | ||||||
|  | 	} | ||||||
|  |     } else { | ||||||
|  | 	fbValidateGC(gc, changes, drawable); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     gc->ops = &glamor_gc_ops; |     gc->ops = &glamor_gc_ops; | ||||||
| } | } | ||||||
|  | @ -399,3 +587,56 @@ glamor_create_gc(GCPtr gc) | ||||||
| 
 | 
 | ||||||
|     return TRUE; |     return TRUE; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | Bool | ||||||
|  | glamor_prepare_access_window(WindowPtr window) | ||||||
|  | { | ||||||
|  |     if (window->backgroundState == BackgroundPixmap) { | ||||||
|  |         if (!glamor_prepare_access(&window->background.pixmap->drawable, | ||||||
|  | 				   GLAMOR_ACCESS_RO)) | ||||||
|  | 	    return FALSE; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (window->borderIsPixel == FALSE) { | ||||||
|  |         if (!glamor_prepare_access(&window->border.pixmap->drawable, | ||||||
|  | 				   GLAMOR_ACCESS_RO)) { | ||||||
|  | 	    if (window->backgroundState == BackgroundPixmap) | ||||||
|  | 		glamor_finish_access(&window->background.pixmap->drawable); | ||||||
|  | 	    return FALSE; | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  |     return TRUE; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | glamor_finish_access_window(WindowPtr window) | ||||||
|  | { | ||||||
|  |     if (window->backgroundState == BackgroundPixmap) | ||||||
|  |         glamor_finish_access(&window->background.pixmap->drawable); | ||||||
|  | 
 | ||||||
|  |     if (window->borderIsPixel == FALSE) | ||||||
|  |         glamor_finish_access(&window->border.pixmap->drawable); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Bool | ||||||
|  | glamor_change_window_attributes(WindowPtr window, unsigned long mask) | ||||||
|  | { | ||||||
|  |     Bool ret; | ||||||
|  | 
 | ||||||
|  |     if (!glamor_prepare_access_window(window)) | ||||||
|  | 	return FALSE; | ||||||
|  |     ret = fbChangeWindowAttributes(window, mask); | ||||||
|  |     glamor_finish_access_window(window); | ||||||
|  |     return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | RegionPtr | ||||||
|  | glamor_bitmap_to_region(PixmapPtr pixmap) | ||||||
|  | { | ||||||
|  |   RegionPtr ret; | ||||||
|  |   if (!glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RO)) | ||||||
|  |     return NULL; | ||||||
|  |   ret = fbPixmapToRegion(pixmap); | ||||||
|  |   glamor_finish_access(&pixmap->drawable); | ||||||
|  |   return ret; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -31,6 +31,11 @@ | ||||||
| #include "glamor.h" | #include "glamor.h" | ||||||
| #include <GL/glew.h> | #include <GL/glew.h> | ||||||
| 
 | 
 | ||||||
|  | typedef enum glamor_access { | ||||||
|  |     GLAMOR_ACCESS_RO, | ||||||
|  |     GLAMOR_ACCESS_RW, | ||||||
|  | } glamor_access_t; | ||||||
|  | 
 | ||||||
| typedef struct glamor_transform_uniforms { | typedef struct glamor_transform_uniforms { | ||||||
|     GLint x_bias; |     GLint x_bias; | ||||||
|     GLint x_scale; |     GLint x_scale; | ||||||
|  | @ -55,6 +60,8 @@ typedef struct glamor_screen_private { | ||||||
|     GetImageProcPtr saved_get_image; |     GetImageProcPtr saved_get_image; | ||||||
|     CompositeProcPtr saved_composite; |     CompositeProcPtr saved_composite; | ||||||
|     TrapezoidsProcPtr saved_trapezoids; |     TrapezoidsProcPtr saved_trapezoids; | ||||||
|  |     ChangeWindowAttributesProcPtr saved_change_window_attributes; | ||||||
|  |     BitmapToRegionProcPtr saved_bitmap_to_region; | ||||||
| 
 | 
 | ||||||
|     /* glamor_solid */ |     /* glamor_solid */ | ||||||
|     GLint solid_prog; |     GLint solid_prog; | ||||||
|  | @ -78,6 +85,7 @@ typedef struct glamor_screen_private { | ||||||
| typedef struct glamor_pixmap_private { | typedef struct glamor_pixmap_private { | ||||||
|     GLuint tex; |     GLuint tex; | ||||||
|     GLuint fb; |     GLuint fb; | ||||||
|  |     GLuint pbo; | ||||||
| } glamor_pixmap_private; | } glamor_pixmap_private; | ||||||
| 
 | 
 | ||||||
| extern DevPrivateKey glamor_screen_private_key; | extern DevPrivateKey glamor_screen_private_key; | ||||||
|  | @ -117,6 +125,10 @@ RegionPtr | ||||||
| glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, | glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, | ||||||
| 		 int srcx, int srcy, int width, int height, int dstx, int dsty); | 		 int srcx, int srcy, int width, int height, int dstx, int dsty); | ||||||
| /* glamor_core.c */ | /* glamor_core.c */ | ||||||
|  | Bool glamor_prepare_access(DrawablePtr drawable, glamor_access_t access); | ||||||
|  | void glamor_finish_access(DrawablePtr drawable); | ||||||
|  | Bool glamor_prepare_access_window(WindowPtr window); | ||||||
|  | void glamor_finish_access_window(WindowPtr window); | ||||||
| Bool glamor_create_gc(GCPtr gc); | Bool glamor_create_gc(GCPtr gc); | ||||||
| void glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple, | void glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple, | ||||||
| 		    int x, int y, int width, int height, | 		    int x, int y, int width, int height, | ||||||
|  | @ -134,6 +146,8 @@ void glamor_get_transform_uniform_locations(GLint prog, | ||||||
| 					    glamor_transform_uniforms *uniform_locations); | 					    glamor_transform_uniforms *uniform_locations); | ||||||
| void glamor_set_transform_for_pixmap(PixmapPtr pixmap, | void glamor_set_transform_for_pixmap(PixmapPtr pixmap, | ||||||
| 				     glamor_transform_uniforms *uniform_locations); | 				     glamor_transform_uniforms *uniform_locations); | ||||||
|  | Bool glamor_change_window_attributes(WindowPtr pWin, unsigned long mask); | ||||||
|  | RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap); | ||||||
| 
 | 
 | ||||||
| /* glamor_fill.c */ | /* glamor_fill.c */ | ||||||
| void glamor_fill(DrawablePtr drawable, | void glamor_fill(DrawablePtr drawable, | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue