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
Block a user