glamor: Add new feature which is to flip output on y axis.

Due to the coordinate system on EGL is different from FBO
object. To support EGL surface well, we add this new feature.
When calling glamor_init from EGL ddx driver, it should use
the new flag GLAMOR_INVERTED_Y_AXIS.
This commit is contained in:
Zhigang Gong 2011-05-12 01:08:38 +08:00
parent 6dae8dc7ea
commit eb3487a448
11 changed files with 193 additions and 43 deletions

View File

@ -162,10 +162,15 @@ glamor_wakeup_handler(void *data, int result, void *last_select_mask)
/** Set up glamor for an already-configured GL context. */
Bool
glamor_init(ScreenPtr screen)
glamor_init(ScreenPtr screen, unsigned int flags)
{
glamor_screen_private *glamor_priv;
if (flags & ~GLAMOR_VALID_FLAGS) {
ErrorF("glamor_init: Invalid flags %x\n", flags);
return FALSE;
}
#ifdef RENDER
PictureScreenPtr ps = GetPictureScreenIfSet(screen);
#endif
@ -174,6 +179,10 @@ glamor_init(ScreenPtr screen)
if (glamor_priv == NULL)
return FALSE;
if (flags & GLAMOR_INVERTED_Y_AXIS) {
glamor_priv->yInverted = 1;
} else
glamor_priv->yInverted = 0;
if (!dixRegisterPrivateKey(glamor_screen_private_key,PRIVATE_SCREEN,
0)) {

View File

@ -38,6 +38,9 @@
#endif /* GLAMOR_H */
Bool glamor_init(ScreenPtr screen);
#define GLAMOR_INVERTED_Y_AXIS 0x1
#define GLAMOR_VALID_FLAGS (GLAMOR_INVERTED_Y_AXIS)
Bool glamor_init(ScreenPtr screen, unsigned int flags);
void glamor_fini(ScreenPtr screen);
void glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex);

View File

@ -45,6 +45,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
glamor_pixmap_private *src_pixmap_priv;
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
int dst_x_off, dst_y_off, src_x_off, src_y_off, i;
if (src == dst) {
@ -94,6 +95,18 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
src_y_off += dy;
for (i = 0; i < nbox; i++) {
if(glamor_priv->yInverted) {
glBlitFramebufferEXT((box[i].x1 + dx + src_x_off),
(box[i].y1 + src_y_off),
(box[i].x2 + dx + src_x_off),
(box[i].y2 + src_y_off),
(box[i].x1 + dst_x_off),
(box[i].y1 + dst_y_off),
(box[i].x2 + dst_x_off),
(box[i].y2 + dst_y_off),
GL_COLOR_BUFFER_BIT,
GL_NEAREST);
} else {
int flip_dst_y1 = dst_pixmap->drawable.height - (box[i].y2 + dst_y_off);
int flip_dst_y2 = dst_pixmap->drawable.height - (box[i].y1 + dst_y_off);
int flip_src_y1 = src_pixmap->drawable.height - (box[i].y2 + src_y_off);
@ -109,6 +122,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
flip_dst_y2,
GL_COLOR_BUFFER_BIT,
GL_NEAREST);
}
}
return TRUE;
@ -125,6 +139,8 @@ glamor_copy_n_to_n_copypixels(DrawablePtr src,
{
ScreenPtr screen = dst->pScreen;
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
glamor_screen_private *glamor_priv =
glamor_get_screen_private(screen);
int x_off, y_off, i;
if (src != dst) {
@ -161,6 +177,15 @@ glamor_copy_n_to_n_copypixels(DrawablePtr src,
glamor_get_drawable_deltas(dst, dst_pixmap, &x_off, &y_off);
for (i = 0; i < nbox; i++) {
if(glamor_priv->yInverted) {
glRasterPos2i(box[i].x1 + x_off,
box[i].y1 + y_off);
glCopyPixels(box[i].x1 + dx + x_off,
box[i].y1 + dy + y_off,
box[i].x2 - box[i].x1,
box[i].y2 - box[i].y1,
GL_COLOR);
} else {
int flip_y1 = dst_pixmap->drawable.height - box[i].y2 + y_off;
glRasterPos2i(box[i].x1 + x_off,
flip_y1);
@ -169,6 +194,7 @@ glamor_copy_n_to_n_copypixels(DrawablePtr src,
box[i].x2 - box[i].x1,
box[i].y2 - box[i].y1,
GL_COLOR);
}
}
return TRUE;
@ -235,23 +261,39 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
glUseProgramObjectARB(glamor_priv->finish_access_prog);
for (i = 0; i < nbox; i++) {
vertices[0][0] = v_from_x_coord_x(dst_pixmap, box[i].x1 + dst_x_off);
vertices[0][1] = v_from_x_coord_y(dst_pixmap, box[i].y1 + dst_y_off);
vertices[1][0] = v_from_x_coord_x(dst_pixmap, box[i].x2 + dst_x_off);
vertices[1][1] = v_from_x_coord_y(dst_pixmap, box[i].y1 + dst_y_off);
vertices[2][0] = v_from_x_coord_x(dst_pixmap, box[i].x2 + dst_x_off);
vertices[2][1] = v_from_x_coord_y(dst_pixmap, box[i].y2 + dst_y_off);
vertices[3][0] = v_from_x_coord_x(dst_pixmap, box[i].x1 + dst_x_off);
texcoords[0][0] = t_from_x_coord_x(src_pixmap, box[i].x1 + dx);
texcoords[1][0] = t_from_x_coord_x(src_pixmap, box[i].x2 + dx);
texcoords[2][0] = t_from_x_coord_x(src_pixmap, box[i].x2 + dx);
texcoords[3][0] = t_from_x_coord_x(src_pixmap, box[i].x1 + dx);
if(glamor_priv->yInverted) {
vertices[0][1] = v_from_x_coord_y_inverted(dst_pixmap, box[i].y1 + dst_y_off);
vertices[1][1] = v_from_x_coord_y_inverted(dst_pixmap, box[i].y1 + dst_y_off);
vertices[2][1] = v_from_x_coord_y_inverted(dst_pixmap, box[i].y2 + dst_y_off);
vertices[3][1] = v_from_x_coord_y_inverted(dst_pixmap, box[i].y2 + dst_y_off);
texcoords[0][1] = t_from_x_coord_y_inverted(src_pixmap, box[i].y1 + dy);
texcoords[1][1] = t_from_x_coord_y_inverted(src_pixmap, box[i].y1 + dy);
texcoords[2][1] = t_from_x_coord_y_inverted(src_pixmap, box[i].y2 + dy);
texcoords[3][1] = t_from_x_coord_y_inverted(src_pixmap, box[i].y2 + dy);
} else {
vertices[0][1] = v_from_x_coord_y(dst_pixmap, box[i].y1 + dst_y_off);
vertices[1][1] = v_from_x_coord_y(dst_pixmap, box[i].y1 + dst_y_off);
vertices[2][1] = v_from_x_coord_y(dst_pixmap, box[i].y2 + dst_y_off);
vertices[3][1] = v_from_x_coord_y(dst_pixmap, box[i].y2 + dst_y_off);
texcoords[0][0] = t_from_x_coord_x(src_pixmap, box[i].x1 + dx);
texcoords[0][1] = t_from_x_coord_y(src_pixmap, box[i].y1 + dy);
texcoords[1][0] = t_from_x_coord_x(src_pixmap, box[i].x2 + dx);
texcoords[1][1] = t_from_x_coord_y(src_pixmap, box[i].y1 + dy);
texcoords[2][0] = t_from_x_coord_x(src_pixmap, box[i].x2 + dx);
texcoords[2][1] = t_from_x_coord_y(src_pixmap, box[i].y2 + dy);
texcoords[3][0] = t_from_x_coord_x(src_pixmap, box[i].x1 + dx);
texcoords[3][1] = t_from_x_coord_y(src_pixmap, box[i].y2 + dy);
}
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}

View File

@ -294,12 +294,14 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
unsigned int stride, read_stride, x, y;
GLenum format, type;
uint8_t *data, *read;
glamor_screen_private *glamor_priv =
glamor_get_screen_private(drawable->pScreen);
if (pixmap_priv == NULL)
return TRUE;
if (pixmap_priv->fb == 0) {
ScreenPtr screen = pixmap->drawable.pScreen;
ScreenPtr screen = pixmap->drawable.pScreen;
PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
if (pixmap != screen_pixmap)
@ -343,11 +345,13 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
glPixelStorei(GL_PACK_ROW_LENGTH, read_stride);
}
if (GLEW_MESA_pack_invert && drawable->depth != 1) {
glPixelStorei(GL_PACK_INVERT_MESA, 1);
if (!glamor_priv->yInverted)
glPixelStorei(GL_PACK_INVERT_MESA, 1);
glReadPixels(0, 0,
pixmap->drawable.width, pixmap->drawable.height,
format, type, data);
glPixelStorei(GL_PACK_INVERT_MESA, 0);
if (!glamor_priv->yInverted)
glPixelStorei(GL_PACK_INVERT_MESA, 0);
} else {
glGenBuffersARB(1, &pixmap_priv->pbo);
glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
@ -362,10 +366,15 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
if (pixmap->drawable.depth == 1) {
for (y = 0; y < pixmap->drawable.height; y++) {
uint8_t *read_row = read +
read_stride * (pixmap->drawable.height - y - 1);
uint8_t *read_row;
uint8_t *write_row = data + y * stride;
if (glamor_priv->yInverted)
read_row = read + read_stride * y;
else
read_row = read +
read_stride * (pixmap->drawable.height - y - 1);
for (x = 0; x < pixmap->drawable.width; x++) {
int index = x / 8;
int bit = 1 << (x % 8);
@ -378,6 +387,9 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
}
} else {
for (y = 0; y < pixmap->drawable.height; y++)
if (glamor_priv->yInverted)
memcpy(data + y * stride, read + y * stride, stride);
else
memcpy(data + y * stride,
read + (pixmap->drawable.height - y - 1) * stride, stride);
}
@ -452,10 +464,20 @@ glamor_finish_access(DrawablePtr drawable)
{1, 1},
{1, 0},
{0, 0}};
GLuint tex;
static float texcoords_inverted[4][2] = {{0, 0},
{1, 0},
{1, 1},
{0, 1}};
static float *ptexcoords;
if (pixmap_priv == NULL)
return;
if (glamor_priv->yInverted)
ptexcoords = texcoords_inverted;
else
ptexcoords = texcoords;
if (pixmap_priv->fb == 0) {
ScreenPtr screen = pixmap->drawable.pScreen;
@ -496,7 +518,7 @@ glamor_finish_access(DrawablePtr drawable)
glEnableClientState(GL_VERTEX_ARRAY);
glClientActiveTexture(GL_TEXTURE0);
glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords);
glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, ptexcoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);

View File

@ -153,14 +153,21 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
glEnableClientState(GL_VERTEX_ARRAY);
vertices[0][0] = v_from_x_coord_x(pixmap, x1);
vertices[0][1] = v_from_x_coord_y(pixmap, y1);
vertices[1][0] = v_from_x_coord_x(pixmap, x2);
vertices[1][1] = v_from_x_coord_y(pixmap, y1);
vertices[2][0] = v_from_x_coord_x(pixmap, x2);
vertices[2][1] = v_from_x_coord_y(pixmap, y2);
vertices[3][0] = v_from_x_coord_x(pixmap, x1);
vertices[3][1] = v_from_x_coord_y(pixmap, y2);
if (glamor_priv->yInverted) {
vertices[0][1] = v_from_x_coord_y_inverted(pixmap, y1);
vertices[1][1] = v_from_x_coord_y_inverted(pixmap, y1);
vertices[2][1] = v_from_x_coord_y_inverted(pixmap, y2);
vertices[3][1] = v_from_x_coord_y_inverted(pixmap, y2);
} else {
vertices[0][1] = v_from_x_coord_y(pixmap, y1);
vertices[1][1] = v_from_x_coord_y(pixmap, y1);
vertices[2][1] = v_from_x_coord_y(pixmap, y2);
vertices[3][1] = v_from_x_coord_y(pixmap, y2);
}
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glDisableClientState(GL_VERTEX_ARRAY);

View File

@ -53,6 +53,8 @@ glamor_get_spans(DrawablePtr drawable,
{
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
GLenum format, type;
glamor_screen_private *glamor_priv =
glamor_get_screen_private(drawable->pScreen);
int i, j;
uint8_t *temp_dst = NULL, *readpixels_dst = (uint8_t *)dst;
int x_off, y_off;
@ -85,12 +87,21 @@ glamor_get_spans(DrawablePtr drawable,
glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
for (i = 0; i < count; i++) {
if (glamor_priv->yInverted) {
glReadPixels(points[i].x + x_off,
(points[i].y + y_off),
widths[i],
1,
format, type,
readpixels_dst);
} else {
glReadPixels(points[i].x + x_off,
pixmap->drawable.height - 1 - (points[i].y + y_off),
widths[i],
1,
format, type,
readpixels_dst);
}
if (temp_dst) {
for (j = 0; j < widths[i]; j++) {
set_bit((uint8_t *)dst, j, temp_dst[j] & 0x1);

View File

@ -142,7 +142,7 @@ typedef struct glamor_screen_private {
BitmapToRegionProcPtr saved_bitmap_to_region;
char *delayed_fallback_string;
int yInverted;
GLuint vbo;
int vbo_offset;
int vbo_size;
@ -268,6 +268,13 @@ v_from_x_coord_y(PixmapPtr pixmap, int y)
return (float)y / pixmap->drawable.height * -2.0 + 1.0;
}
static inline float
v_from_x_coord_y_inverted(PixmapPtr pixmap, int y)
{
return (float)y / pixmap->drawable.height * 2.0 - 1.0;
}
static inline float
t_from_x_coord_x(PixmapPtr pixmap, int x)
{
@ -280,6 +287,13 @@ t_from_x_coord_y(PixmapPtr pixmap, int y)
return 1.0 - (float)y / pixmap->drawable.height;
}
static inline float
t_from_x_coord_y_inverted(PixmapPtr pixmap, int y)
{
return (float)y / pixmap->drawable.height;
}
/* glamor.c */
PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable);

View File

@ -377,13 +377,9 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
src_y2 = (float)(y2 - y) / h;
vertices[0][0] = v_from_x_coord_x(pixmap, x1 + x_off);
vertices[0][1] = v_from_x_coord_y(pixmap, y1 + y_off);
vertices[1][0] = v_from_x_coord_x(pixmap, x2 + x_off);
vertices[1][1] = v_from_x_coord_y(pixmap, y1 + y_off);
vertices[2][0] = v_from_x_coord_x(pixmap, x2 + x_off);
vertices[2][1] = v_from_x_coord_y(pixmap, y2 + y_off);
vertices[3][0] = v_from_x_coord_x(pixmap, x1 + x_off);
vertices[3][1] = v_from_x_coord_y(pixmap, y2 + y_off);
texcoords[0][0] = src_x1;
texcoords[0][1] = src_y1;
@ -393,7 +389,23 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
texcoords[2][1] = src_y2;
texcoords[3][0] = src_x1;
texcoords[3][1] = src_y2;
if (glamor_priv->yInverted) {
vertices[0][1] = v_from_x_coord_y_inverted(pixmap, y1 + y_off);
vertices[1][1] = v_from_x_coord_y_inverted(pixmap, y1 + y_off);
vertices[2][1] = v_from_x_coord_y_inverted(pixmap, y2 + y_off);
vertices[3][1] = v_from_x_coord_y_inverted(pixmap, y2 + y_off);
} else {
vertices[0][1] = v_from_x_coord_y(pixmap, y1 + y_off);
vertices[1][1] = v_from_x_coord_y(pixmap, y1 + y_off);
vertices[2][1] = v_from_x_coord_y(pixmap, y2 + y_off);
vertices[3][1] = v_from_x_coord_y(pixmap, y2 + y_off);
}
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}

View File

@ -556,6 +556,8 @@ glamor_set_transformed_point(PicturePtr picture, PixmapPtr pixmap,
float result[3];
int i;
float tx, ty;
ScreenPtr screen = picture->pDrawable->pScreen;
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
if (picture->transform) {
for (i = 0; i < 3; i++) {
@ -570,7 +572,10 @@ glamor_set_transformed_point(PicturePtr picture, PixmapPtr pixmap,
ty = y;
}
texcoord[0] = t_from_x_coord_x(pixmap, tx);
texcoord[1] = t_from_x_coord_y(pixmap, ty);
if (glamor_priv->yInverted)
texcoord[1] = t_from_x_coord_y_inverted(pixmap, ty);
else
texcoord[1] = t_from_x_coord_y(pixmap, ty);
}
static void
@ -887,21 +892,33 @@ glamor_composite_with_shader(CARD8 op,
for (i = 0; i < REGION_NUM_RECTS(&region); i++) {
vertices[0] = v_from_x_coord_x(dest_pixmap,
box[i].x1 + dest_x_off);
vertices[1] = v_from_x_coord_y(dest_pixmap,
box[i].y1 + dest_y_off);
vertices[2] = v_from_x_coord_x(dest_pixmap,
box[i].x2 + dest_x_off);
vertices[3] = v_from_x_coord_y(dest_pixmap,
box[i].y1 + dest_y_off);
vertices[4] = v_from_x_coord_x(dest_pixmap,
box[i].x2 + dest_x_off);
vertices[5] = v_from_x_coord_y(dest_pixmap,
box[i].y2 + dest_y_off);
vertices[6] = v_from_x_coord_x(dest_pixmap,
box[i].x1 + dest_x_off);
vertices[7] = v_from_x_coord_y(dest_pixmap,
if (glamor_priv->yInverted) {
vertices[1] = v_from_x_coord_y_inverted(dest_pixmap,
box[i].y1 + dest_y_off);
vertices[3] = v_from_x_coord_y_inverted(dest_pixmap,
box[i].y1 + dest_y_off);
vertices[5] = v_from_x_coord_y_inverted(dest_pixmap,
box[i].y2 + dest_y_off);
vertices[7] = v_from_x_coord_y_inverted(dest_pixmap,
box[i].y2 + dest_y_off);
} else {
vertices[1] = v_from_x_coord_y(dest_pixmap,
box[i].y1 + dest_y_off);
vertices[3] = v_from_x_coord_y(dest_pixmap,
box[i].y1 + dest_y_off);
vertices[5] = v_from_x_coord_y(dest_pixmap,
box[i].y2 + dest_y_off);
vertices[7] = v_from_x_coord_y(dest_pixmap,
box[i].y2 + dest_y_off);
}
if (key.source != SHADER_SOURCE_SOLID) {
int tx1 = box[i].x1 + x_source - x_dest;
int ty1 = box[i].y1 + y_source - y_dest;

View File

@ -120,23 +120,36 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
glEnable(GL_TEXTURE_2D);
vertices[0][0] = v_from_x_coord_x(pixmap, x1);
vertices[0][1] = v_from_x_coord_y(pixmap, y1);
vertices[1][0] = v_from_x_coord_x(pixmap, x2);
vertices[1][1] = v_from_x_coord_y(pixmap, y1);
vertices[2][0] = v_from_x_coord_x(pixmap, x2);
vertices[2][1] = v_from_x_coord_y(pixmap, y2);
vertices[3][0] = v_from_x_coord_x(pixmap, x1);
vertices[3][1] = v_from_x_coord_y(pixmap, y2);
source_texcoords[0][0] = t_from_x_coord_x(tile, tile_x1);
source_texcoords[0][1] = t_from_x_coord_y(tile, tile_y1);
source_texcoords[1][0] = t_from_x_coord_x(tile, tile_x2);
source_texcoords[1][1] = t_from_x_coord_y(tile, tile_y1);
source_texcoords[2][0] = t_from_x_coord_x(tile, tile_x2);
source_texcoords[2][1] = t_from_x_coord_y(tile, tile_y2);
source_texcoords[3][0] = t_from_x_coord_x(tile, tile_x1);
source_texcoords[3][1] = t_from_x_coord_y(tile, tile_y2);
if (glamor_priv->yInverted) {
vertices[0][1] = v_from_x_coord_y_inverted(pixmap, y1);
vertices[1][1] = v_from_x_coord_y_inverted(pixmap, y1);
vertices[2][1] = v_from_x_coord_y_inverted(pixmap, y2);
vertices[3][1] = v_from_x_coord_y_inverted(pixmap, y2);
source_texcoords[0][1] = t_from_x_coord_y_inverted(tile, tile_y1);
source_texcoords[1][1] = t_from_x_coord_y_inverted(tile, tile_y1);
source_texcoords[2][1] = t_from_x_coord_y_inverted(tile, tile_y2);
source_texcoords[3][1] = t_from_x_coord_y_inverted(tile, tile_y2);
} else {
vertices[0][1] = v_from_x_coord_y(pixmap, y1);
vertices[1][1] = v_from_x_coord_y(pixmap, y1);
vertices[2][1] = v_from_x_coord_y(pixmap, y2);
vertices[3][1] = v_from_x_coord_y(pixmap, y2);
source_texcoords[0][1] = t_from_x_coord_y(tile, tile_y1);
source_texcoords[1][1] = t_from_x_coord_y(tile, tile_y1);
source_texcoords[2][1] = t_from_x_coord_y(tile, tile_y2);
source_texcoords[3][1] = t_from_x_coord_y(tile, tile_y2);
}
glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
glEnableClientState(GL_VERTEX_ARRAY);

View File

@ -45,7 +45,7 @@ ephyr_glamor_init(ScreenPtr screen)
ephyr_glamor_host_create_context(kd_screen);
glamor_init(screen);
glamor_init(screen, 0);
return TRUE;
}