From ca1908e11dcb56cb952f6bce55503e932aa9a27c Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Wed, 22 Jun 2011 14:33:38 +0800 Subject: [PATCH] glamor: Concentrate and reduce some coords processing code. Concentrate the verties and texture coords processing code to a new file glamor_utils.h. Change most of the code to macro. Will have some performance benefit on slow machine. And reduce most of the duplicate code when calculate the normalized coords. Signed-off-by: Zhigang Gong --- glamor/glamor_copyarea.c | 52 +++++++--------- glamor/glamor_fill.c | 32 ++++------ glamor/glamor_getspans.c | 16 +++-- glamor/glamor_priv.h | 41 +------------ glamor/glamor_putimage.c | 106 +++++++++++++++------------------ glamor/glamor_render.c | 119 ++++++++++++------------------------- glamor/glamor_tile.c | 72 +++++++++++------------ glamor/glamor_utils.h | 124 +++++++++++++++++++++++++++++++++++++++ 8 files changed, 287 insertions(+), 275 deletions(-) create mode 100644 glamor/glamor_utils.h diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index 766c9e2b3..55437715a 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -199,11 +199,13 @@ glamor_copy_n_to_n_textured(DrawablePtr src, PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); int i; - float vertices[4][2], texcoords[4][2]; + float vertices[8], texcoords[8]; glamor_pixmap_private *src_pixmap_priv; glamor_pixmap_private *dst_pixmap_priv; int src_x_off, src_y_off, dst_x_off, dst_y_off; enum glamor_pixmap_status src_status = GLAMOR_NONE; + GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale; + src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap); @@ -237,6 +239,9 @@ glamor_copy_n_to_n_textured(DrawablePtr src, } glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv); + pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale); + pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale); + glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off); glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off); @@ -258,42 +263,25 @@ glamor_copy_n_to_n_textured(DrawablePtr src, assert(GLEW_ARB_fragment_shader); glUseProgramObjectARB(glamor_priv->finish_access_prog[0]); + for (i = 0; i < nbox; i++) { - vertices[0][0] = v_from_x_coord_x(dst_pixmap, box[i].x1 + dst_x_off); - vertices[1][0] = v_from_x_coord_x(dst_pixmap, box[i].x2 + dst_x_off); - vertices[2][0] = v_from_x_coord_x(dst_pixmap, box[i].x2 + dst_x_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); + glamor_set_normalize_vcoords(dst_xscale, dst_yscale, + box[i].x1 + dst_x_off, + box[i].y1 + dst_y_off, + box[i].x2 + dst_x_off, + box[i].y2 + dst_y_off, + glamor_priv->yInverted, + vertices); - if(glamor_priv->yInverted) { + glamor_set_normalize_tcoords(src_xscale, src_yscale, + box[i].x1 + dx, box[i].y1 + dy, + box[i].x2 + dx, box[i].y2 + dy, + glamor_priv->yInverted, + texcoords); - 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][1] = t_from_x_coord_y(src_pixmap, box[i].y1 + dy); - texcoords[1][1] = t_from_x_coord_y(src_pixmap, box[i].y1 + dy); - texcoords[2][1] = t_from_x_coord_y(src_pixmap, box[i].y2 + dy); - texcoords[3][1] = t_from_x_coord_y(src_pixmap, box[i].y2 + dy); - } - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } glUseProgramObjectARB(0); diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index fade2b3cd..48f85ce38 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -146,14 +146,16 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, { ScreenPtr screen = pixmap->drawable.pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); int x1 = x; int x2 = x + width; int y1 = y; int y2 = y + height; GLfloat color[4]; - float vertices[4][2]; - - if (glamor_set_destination_pixmap(pixmap)) { + float vertices[8]; + GLfloat xscale, yscale; + + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { glamor_fallback("dest has no fbo.\n"); goto fail; } @@ -162,6 +164,9 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, glamor_fallback("Failedto set planemask in glamor_solid.\n"); goto fail; } + + glamor_set_destination_pixmap_priv_nc(pixmap_priv); + glUseProgramObjectARB(glamor_priv->solid_prog); glamor_get_rgba_from_pixel(fg_pixel, &color[0], @@ -174,22 +179,11 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); glEnableClientState(GL_VERTEX_ARRAY); - vertices[0][0] = v_from_x_coord_x(pixmap, x1); - vertices[1][0] = v_from_x_coord_x(pixmap, x2); - vertices[2][0] = v_from_x_coord_x(pixmap, x2); - vertices[3][0] = v_from_x_coord_x(pixmap, x1); - - 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); - } + pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale); + + glamor_set_normalize_vcoords(xscale, yscale, x1, y1, x2, y2, + glamor_priv->yInverted, + vertices); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisableClientState(GL_VERTEX_ARRAY); diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c index 10fa2a2c3..7fe05f993 100644 --- a/glamor/glamor_getspans.c +++ b/glamor/glamor_getspans.c @@ -42,11 +42,17 @@ glamor_get_spans(DrawablePtr drawable, PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); GLenum format, type; int ax; - glamor_screen_private *glamor_priv = - glamor_get_screen_private(drawable->pScreen); + glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen); + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); int i; uint8_t *readpixels_dst = (uint8_t *)dst; int x_off, y_off; + + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { + glamor_fallback("pixmap has no fbo.\n"); + goto fail; + } + if (glamor_get_tex_format_type_from_pixmap(pixmap, &format, &type, @@ -57,10 +63,8 @@ glamor_get_spans(DrawablePtr drawable, goto fail; } - if (glamor_set_destination_pixmap(pixmap)) { - glamor_fallback("pixmap has no fbo.\n"); - goto fail; - } + glamor_set_destination_pixmap_priv_nc(pixmap_priv); + glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off); for (i = 0; i < count; i++) { if (glamor_priv->yInverted) { diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index cf293b5dc..5b457e7fc 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -505,44 +505,6 @@ glamor_pm_is_solid(DrawablePtr drawable, unsigned long planemask) extern int glamor_debug_level; -static inline float -v_from_x_coord_x(PixmapPtr pixmap, int x) -{ - return (float)x / pixmap->drawable.width * 2.0 - 1.0; -} - -static inline float -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) -{ - return (float)x / pixmap->drawable.width; -} - -static inline float -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); @@ -791,4 +753,7 @@ glamor_picture_format_fixup(PicturePtr picture, glamor_pixmap_private *pixmap_pr #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD + +#include"glamor_utils.h" + #endif /* GLAMOR_PRIV_H */ diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index d056576a0..e61425d11 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -87,17 +87,6 @@ glamor_init_putimage_shaders(ScreenPtr screen) glUseProgramObjectARB(0); } -static int -y_flip(PixmapPtr pixmap, int y) -{ - ScreenPtr screen = pixmap->drawable.pScreen; - PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); - - if (pixmap == screen_pixmap) - return (pixmap->drawable.height - 1) - y; - else - return y; -} /* Do an XYBitmap putimage. The bits are byte-aligned rows of bitmap * data (where each row starts at a bit index of left_pad), and the @@ -110,6 +99,21 @@ y_flip(PixmapPtr pixmap, int y) * case we might be better off just doing the fg/bg choosing in the CPU * and just draw the resulting texture to the destination. */ +#if 0 + +static int +y_flip(PixmapPtr pixmap, int y) +{ + ScreenPtr screen = pixmap->drawable.pScreen; + PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); + + if (pixmap == screen_pixmap) + return (pixmap->drawable.height - 1) - y; + else + return y; +} + + static void glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc, int x, int y, int w, int h, int left_pad, @@ -124,25 +128,27 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc, RegionPtr clip; BoxPtr box; int nbox; - float dest_coords[4][2]; + float dest_coords[8]; const float bitmap_coords[8] = { 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, }; + GLfloat xscale, yscale; + glamor_pixmap_private *pixmap_priv; + + pixmap_priv = glamor_get_pixmap_private(pixmap); + pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale); - dest_coords[0][0] = v_from_x_coord_x(pixmap, x); - dest_coords[0][1] = v_from_x_coord_y(pixmap, y); - dest_coords[1][0] = v_from_x_coord_x(pixmap, x + w); - dest_coords[1][1] = v_from_x_coord_y(pixmap, y); - dest_coords[2][0] = v_from_x_coord_x(pixmap, x + w); - dest_coords[2][1] = v_from_x_coord_y(pixmap, y + h); - dest_coords[3][0] = v_from_x_coord_x(pixmap, x); - dest_coords[3][1] = v_from_x_coord_y(pixmap, y + h); + glamor_set_normalize_vcoords(xscale, yscale, + x, y, + x + w, y + h, + glamor_priv->yInverted, + dest_coords); - glamor_fallback("glamor_put_image_xybitmap: disabled\n"); + glamor_fallback("glamor_put_image_xybitmap: disabled\n"); goto fail; if (glamor_priv->put_image_xybitmap_prog == 0) { @@ -237,6 +243,8 @@ fail: glamor_finish_access(drawable); } } +#endif + void glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, @@ -252,13 +260,13 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int nbox; int src_stride = PixmapBytePad(w, drawable->depth); int x_off, y_off; - float vertices[4][2], texcoords[4][2]; + float vertices[8], texcoords[8]; + GLfloat xscale, yscale, txscale, tyscale; GLuint tex; int ax = 0; if (image_format == XYBitmap) { assert(depth == 1); - glamor_put_image_xybitmap(drawable, gc, x, y, w, h, - left_pad, image_format, bits); + goto fail; return; } @@ -319,8 +327,12 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, y += drawable->y; glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off); - clip = fbGetCompositeClip(gc); + + txscale = 1.0/w; + tyscale = 1.0/h; + pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale); + for (nbox = REGION_NUM_RECTS(clip), pbox = REGION_RECTS(clip); nbox--; @@ -330,7 +342,6 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int y1 = y; int x2 = x + w; int y2 = y + h; - float src_x1, src_x2, src_y1, src_y2; if (x1 < pbox->x1) x1 = pbox->x1; @@ -343,41 +354,18 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, if (x1 >= x2 || y1 >= y2) continue; - src_x1 = (float)(x1 - x) / w; - src_y1 = (float)(y1 - y) / h; - src_x2 = (float)(x2 - x) / w; - src_y2 = (float)(y2 - y) / h; + glamor_set_normalize_tcoords( txscale, tyscale, + x1 - x, y1 - y, + x2 - x, y2 - y, + 1, + texcoords); - vertices[0][0] = v_from_x_coord_x(pixmap, x1 + x_off); - vertices[1][0] = v_from_x_coord_x(pixmap, x2 + x_off); - vertices[2][0] = v_from_x_coord_x(pixmap, x2 + x_off); - vertices[3][0] = v_from_x_coord_x(pixmap, x1 + x_off); + glamor_set_normalize_vcoords( xscale, yscale, + x1 + x_off, y1 + y_off, + x2 + x_off, y2 + y_off, + glamor_priv->yInverted, + vertices); - texcoords[0][0] = src_x1; - texcoords[0][1] = src_y1; - texcoords[1][0] = src_x2; - texcoords[1][1] = src_y1; - texcoords[2][0] = src_x2; - 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); } diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index ca27b4d59..f991b0f17 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -533,41 +533,6 @@ good_dest_format(PicturePtr picture) } } -static inline float -xFixedToFloat(pixman_fixed_t val) -{ - return ((float)xFixedToInt(val) + ((float)xFixedFrac(val) / 65536.0)); -} - -static void -glamor_set_transformed_point(PicturePtr picture, PixmapPtr pixmap, - float *texcoord, int x, int y) -{ - 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++) { - result[i] = (xFixedToFloat(picture->transform->matrix[i][0]) * x + - xFixedToFloat(picture->transform->matrix[i][1]) * y + - xFixedToFloat(picture->transform->matrix[i][2])); - } - tx = result[0] / result[2]; - ty = result[1] / result[2]; - } else { - tx = x; - ty = y; - } - texcoord[0] = t_from_x_coord_x(pixmap, tx); - 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 glamor_setup_composite_vbo(ScreenPtr screen) { @@ -756,6 +721,8 @@ glamor_composite_with_shader(CARD8 op, glamor_pixmap_private *source_pixmap_priv = NULL; glamor_pixmap_private *mask_pixmap_priv = NULL; glamor_pixmap_private *dest_pixmap_priv = NULL; + GLfloat dst_xscale, dst_yscale; + GLfloat mask_xscale = 1, mask_yscale = 1, src_xscale = 1, src_yscale = 1; struct shader_key key; glamor_composite_shader *shader; RegionRec region; @@ -768,6 +735,8 @@ glamor_composite_with_shader(CARD8 op, enum glamor_pixmap_status source_status = GLAMOR_NONE; enum glamor_pixmap_status mask_status = GLAMOR_NONE; PictFormatShort saved_source_format = 0; + float src_matrix[9], mask_matrix[9]; + dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) { @@ -972,14 +941,24 @@ glamor_composite_with_shader(CARD8 op, glamor_get_drawable_deltas(dest->pDrawable, dest_pixmap, &dest_x_off, &dest_y_off); + pixmap_priv_get_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale); + + + if (source_pixmap) { glamor_get_drawable_deltas(source->pDrawable, source_pixmap, &source_x_off, &source_y_off); + pixmap_priv_get_scale(source_pixmap_priv, &src_xscale, &src_yscale); + glamor_picture_get_matrixf(source, src_matrix); } + if (mask_pixmap) { glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap, &mask_x_off, &mask_y_off); + pixmap_priv_get_scale(mask_pixmap_priv, &mask_xscale, &mask_yscale); + glamor_picture_get_matrixf(mask, mask_matrix); } + while (nrect--) { INT16 x_source; INT16 y_source; @@ -1025,65 +1004,41 @@ glamor_composite_with_shader(CARD8 op, box = REGION_RECTS(®ion); for (i = 0; i < REGION_NUM_RECTS(®ion); i++) { - vertices[0] = v_from_x_coord_x(dest_pixmap, - box[i].x1 + dest_x_off); - vertices[2] = v_from_x_coord_x(dest_pixmap, - box[i].x2 + dest_x_off); - vertices[4] = v_from_x_coord_x(dest_pixmap, - box[i].x2 + dest_x_off); - vertices[6] = v_from_x_coord_x(dest_pixmap, - box[i].x1 + dest_x_off); + int vx1 = box[i].x1 + dest_x_off; + int vx2 = box[i].x2 + dest_x_off; + int vy1 = box[i].y1 + dest_y_off; + int vy2 = box[i].y2 + dest_y_off; + glamor_set_normalize_vcoords(dst_xscale, dst_yscale, vx1, vy1, vx2, vy2, + glamor_priv->yInverted, vertices); - 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; int tx2 = box[i].x2 + x_source - x_dest; int ty2 = box[i].y2 + y_source - y_dest; - - glamor_set_transformed_point(source, source_pixmap, - source_texcoords + 0, tx1, ty1); - glamor_set_transformed_point(source, source_pixmap, - source_texcoords + 2, tx2, ty1); - glamor_set_transformed_point(source, source_pixmap, - source_texcoords + 4, tx2, ty2); - glamor_set_transformed_point(source, source_pixmap, - source_texcoords + 6, tx1, ty2); - } + if (source->transform) + glamor_set_transformed_normalize_tcoords(src_matrix, src_xscale, src_yscale, + tx1, ty1, tx2, ty2, + glamor_priv->yInverted, + source_texcoords); + else + glamor_set_normalize_tcoords(src_xscale, src_yscale, tx1, ty1, tx2, ty2, + glamor_priv->yInverted, source_texcoords); + } if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) { float tx1 = box[i].x1 + x_mask - x_dest; float ty1 = box[i].y1 + y_mask - y_dest; float tx2 = box[i].x2 + x_mask - x_dest; float ty2 = box[i].y2 + y_mask - y_dest; - - glamor_set_transformed_point(mask, mask_pixmap, - mask_texcoords + 0, tx1, ty1); - glamor_set_transformed_point(mask, mask_pixmap, - mask_texcoords + 2, tx2, ty1); - glamor_set_transformed_point(mask, mask_pixmap, - mask_texcoords + 4, tx2, ty2); - glamor_set_transformed_point(mask, mask_pixmap, - mask_texcoords + 6, tx1, ty2); + if (mask->transform) + glamor_set_transformed_normalize_tcoords(mask_matrix, mask_xscale, mask_yscale, + tx1, ty1, tx2, ty2, + glamor_priv->yInverted, + mask_texcoords); + else + glamor_set_normalize_tcoords(mask_xscale, mask_yscale, tx1, ty1, tx2, ty2, + glamor_priv->yInverted, mask_texcoords); } glamor_emit_composite_rect(screen, source_texcoords, mask_texcoords, vertices); diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c index 2991eddd5..90bf734be 100644 --- a/glamor/glamor_tile.c +++ b/glamor/glamor_tile.c @@ -88,70 +88,64 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, int tile_x2 = tile_x + width; int tile_y1 = tile_y; int tile_y2 = tile_y + height; - glamor_pixmap_private *tile_priv = glamor_get_pixmap_private(tile); - float vertices[4][2]; - float source_texcoords[4][2]; + float vertices[8]; + float source_texcoords[8]; + GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale; + glamor_pixmap_private *src_pixmap_priv; + glamor_pixmap_private *dst_pixmap_priv; + + src_pixmap_priv = glamor_get_pixmap_private(tile); + dst_pixmap_priv = glamor_get_pixmap_private(pixmap); + + if (glamor_priv->tile_prog == 0) { glamor_fallback("Tiling unsupported\n"); goto fail; } - if (glamor_set_destination_pixmap(pixmap)) { - glamor_fallback("dest has no fbo."); - goto fail; + + if (GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) { + glamor_fallback("dest has no fbo."); + goto fail; } - if (tile_priv->gl_tex == 0) { - glamor_fallback("Non-texture tile pixmap\n"); - goto fail; + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) { + /* XXX dynamic uploading candidate. */ + glamor_fallback("Non-texture tile pixmap\n"); + goto fail; } if (!glamor_set_planemask(pixmap, planemask)) { glamor_fallback("unsupported planemask %lx\n", planemask); goto fail; } + + glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv); + pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale); + pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale); + glamor_set_alu(alu); glUseProgramObjectARB(glamor_priv->tile_prog); glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, tile_priv->tex); + glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glEnable(GL_TEXTURE_2D); - vertices[0][0] = v_from_x_coord_x(pixmap, x1); - vertices[1][0] = v_from_x_coord_x(pixmap, x2); - vertices[2][0] = v_from_x_coord_x(pixmap, x2); - vertices[3][0] = v_from_x_coord_x(pixmap, x1); - source_texcoords[0][0] = t_from_x_coord_x(tile, tile_x1); - source_texcoords[1][0] = t_from_x_coord_x(tile, tile_x2); - source_texcoords[2][0] = t_from_x_coord_x(tile, tile_x2); - source_texcoords[3][0] = t_from_x_coord_x(tile, tile_x1); - - 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); + glamor_set_normalize_vcoords(dst_xscale, dst_yscale, + x1, y1,x2, y2, + glamor_priv->yInverted, + vertices); - 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 { + glamor_set_normalize_tcoords(src_xscale, src_yscale, + tile_x1, tile_y1, + tile_x2, tile_y2, + glamor_priv->yInverted, + source_texcoords); - 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); diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h new file mode 100644 index 000000000..b8b437eb8 --- /dev/null +++ b/glamor/glamor_utils.h @@ -0,0 +1,124 @@ +#ifndef GLAMOR_PRIV_H +#error This file can only be included by glamor_priv.h +#endif + +#ifndef __GLAMOR_UTILS_H__ +#define __GLAMOR_UTILS_H__ + +#define v_from_x_coord_x(_xscale_, _x_) ( 2 * (_x_) * (_xscale_) - 1.0) +#define v_from_x_coord_y(_yscale_, _y_) (-2 * (_y_) * (_yscale_) + 1.0) +#define v_from_x_coord_y_inverted(_yscale_, _y_) (2 * (_y_) * (_yscale_) - 1.0) +#define t_from_x_coord_x(_xscale_, _x_) ((_x_) * (_xscale_)) +#define t_from_x_coord_y(_yscale_, _y_) (1.0 - (_y_) * (_yscale_)) +#define t_from_x_coord_y_inverted(_yscale_, _y_) ((_y_) * (_yscale_)) + +#define pixmap_priv_get_scale(_pixmap_priv_, _pxscale_, _pyscale_) \ + do { \ + *(_pxscale_) = 1.0 / (_pixmap_priv_)->container->drawable.width; \ + *(_pyscale_) = 1.0 / (_pixmap_priv_)->container->drawable.height; \ + } while(0) + + +#define xFixedToFloat(_val_) ((float)xFixedToInt(_val_) \ + + ((float)xFixedFrac(_val_) / 65536.0)) + +#define glamor_picture_get_matrixf(_picture_, _matrix_) \ + do { \ + int _i_; \ + if ((_picture_)->transform) \ + { \ + for(_i_ = 0; _i_ < 3; _i_++) \ + { \ + (_matrix_)[_i_ * 3 + 0] = \ + xFixedToFloat((_picture_)->transform->matrix[_i_][0]); \ + (_matrix_)[_i_ * 3 + 1] = \ + xFixedToFloat((_picture_)->transform->matrix[_i_][1]); \ + (_matrix_)[_i_ * 3 + 2] = \ + xFixedToFloat((_picture_)->transform->matrix[_i_][2]); \ + } \ + } \ + } while(0) + +#define glamor_set_transformed_point(matrix, xscale, yscale, texcoord, \ + x, y, yInverted) \ + do { \ + float result[4]; \ + int i; \ + float tx, ty; \ + \ + for (i = 0; i < 3; i++) { \ + result[i] = (matrix)[i * 3] * (x) + (matrix)[i * 3 + 1] * (y) \ + + (matrix)[i * 3 + 2]; \ + } \ + tx = result[0] / result[2]; \ + ty = result[1] / result[2]; \ + \ + (texcoord)[0] = t_from_x_coord_x(xscale, tx); \ + if (yInverted) \ + (texcoord)[1] = t_from_x_coord_y_inverted(yscale, ty); \ + else \ + (texcoord)[1] = t_from_x_coord_y(yscale, ty); \ + } while(0) + + +#define glamor_set_transformed_normalize_tcoords( matrix, \ + xscale, \ + yscale, \ + tx1, ty1, tx2, ty2, \ + yInverted, texcoords) \ + do { \ + glamor_set_transformed_point(matrix, xscale, yscale, \ + texcoords, tx1, ty1, \ + yInverted); \ + glamor_set_transformed_point(matrix, xscale, yscale, \ + texcoords + 2, tx2, ty1, \ + yInverted); \ + glamor_set_transformed_point(matrix, xscale, yscale, \ + texcoords + 4, tx2, ty2, \ + yInverted); \ + glamor_set_transformed_point(matrix, xscale, yscale, \ + texcoords + 6, tx1, ty2, \ + yInverted); \ + } while (0) + +#define glamor_set_normalize_tcoords(xscale, yscale, x1, y1, x2, y2, \ + yInverted, vertices) \ + do { \ + (vertices)[0] = t_from_x_coord_x(xscale, x1); \ + (vertices)[2] = t_from_x_coord_x(xscale, x2); \ + (vertices)[4] = (vertices)[2]; \ + (vertices)[6] = (vertices)[0]; \ + if (yInverted) { \ + (vertices)[1] = t_from_x_coord_y_inverted(yscale, y1); \ + (vertices)[5] = t_from_x_coord_y_inverted(yscale, y2); \ + } \ + else { \ + (vertices)[1] = t_from_x_coord_y(yscale, y1); \ + (vertices)[5] = t_from_x_coord_y(yscale, y2); \ + } \ + (vertices)[3] = (vertices)[1]; \ + (vertices)[7] = (vertices)[5]; \ + } while(0) + + +#define glamor_set_normalize_vcoords(xscale, yscale, x1, y1, x2, y2, \ + yInverted, vertices) \ + do { \ + (vertices)[0] = v_from_x_coord_x(xscale, x1); \ + (vertices)[2] = v_from_x_coord_x(xscale, x2); \ + (vertices)[4] = (vertices)[2]; \ + (vertices)[6] = (vertices)[0]; \ + if (yInverted) { \ + (vertices)[1] = v_from_x_coord_y_inverted(yscale, y1); \ + (vertices)[5] = v_from_x_coord_y_inverted(yscale, y2); \ + } \ + else { \ + (vertices)[1] = v_from_x_coord_y(yscale, y1); \ + (vertices)[5] = v_from_x_coord_y(yscale, y2); \ + } \ + (vertices)[3] = (vertices)[1]; \ + (vertices)[7] = (vertices)[5]; \ + } while(0) + + +#endif