glamor: Implement delayed solid filling.

When we need to solid fill an entire pixmap with a specific color,
we do not need to draw it immediately. We can defer it to the
following occasions:

1. The pixmap will be used as source, then we can just use a shader
   to instead of one copyarea.
2. The pixmap will be used as target, then we can do the filling
   just before drawing new pixel onto it. The filling and drawing
   will have the same target texture, we can save one time of
   fbo context switching.

Actually, for the 2nd case, we have opportunity to further optimize
it. We can just fill the untouched region.

By applying this patch, the cairo-trace for the firefox-planet-gnome's
rendering time decrease to 14seconds from 16 seconds.

Signed-off-by: Zhigang Gong <zhigang.gong@linux.intel.com>
This commit is contained in:
Zhigang Gong 2011-07-20 13:06:23 +08:00
parent 1caf741a4a
commit 5c4d53c512
10 changed files with 246 additions and 77 deletions

View File

@ -98,6 +98,7 @@ glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h, unsigned int te
glamor_set_pixmap_texture(pixmap, w, h, tex);
glamor_priv->screen_fbo = pixmap_priv->fb;
pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE;
}
@ -119,7 +120,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
if (w > 32767 || h > 32767)
return NullPixmap;
if (!glamor_check_fbo_width_height(w,h)
if (!glamor_check_fbo_width_height(w,h)
|| !glamor_check_fbo_depth(depth)
|| usage == GLAMOR_CREATE_PIXMAP_CPU) {
/* MESA can only support upto MAX_WIDTH*MAX_HEIGHT fbo.
@ -201,6 +202,7 @@ glamor_create_screen_pixmap(ScreenPtr screen, int w, int h, int depth,
pixmap_priv->gl_fbo = 1;
pixmap_priv->gl_tex = 1;
pixmap_priv->container = pixmap;
pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE;
screen->CreatePixmap = glamor_create_pixmap;
return pixmap;
@ -369,6 +371,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
glamor_init_putimage_shaders(screen);
glamor_init_finish_access_shaders(screen);
glamor_glyphs_init(screen);
glamor_pixmap_init(screen);
return TRUE;

View File

@ -59,6 +59,9 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
if (src_pixmap_priv->pending_op.type == GLAMOR_PENDING_FILL)
return FALSE;
if (gc) {
if (gc->alu != GXcopy) {
glamor_delayed_fallback(screen, "non-copy ALU\n");
@ -78,6 +81,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
if (glamor_set_destination_pixmap(dst_pixmap)) {
return FALSE;
}
glamor_validate_pixmap(dst_pixmap);
glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->fb);
glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
@ -130,6 +134,7 @@ glamor_copy_n_to_n_copypixels(DrawablePtr src,
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
glamor_screen_private *glamor_priv =
glamor_get_screen_private(screen);
glamor_pixmap_private *pixmap_priv;
int x_off, y_off, i;
if (src != dst) {
glamor_delayed_fallback(screen, "src != dest\n");
@ -147,6 +152,9 @@ glamor_copy_n_to_n_copypixels(DrawablePtr src,
}
}
pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
if (pixmap_priv->pending_op.type == GLAMOR_PENDING_FILL)
return TRUE;
if (glamor_set_destination_pixmap(dst_pixmap)) {
glamor_delayed_fallback(screen, "dst has no fbo.\n");
return FALSE;
@ -234,37 +242,47 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
glamor_set_alu(gc->alu);
if (!glamor_set_planemask(dst_pixmap, gc->planemask))
goto fail;
if (gc->alu != GXcopy) {
glamor_set_destination_pixmap_priv_nc(src_pixmap_priv);
glamor_validate_pixmap(src_pixmap);
}
}
glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
glamor_validate_pixmap(dst_pixmap);
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);
dx += src_x_off;
dy += src_y_off;
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex);
glEnable(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glClientActiveTexture(GL_TEXTURE0);
glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
assert(GLEW_ARB_fragment_shader);
glUseProgramObjectARB(glamor_priv->finish_access_prog[0]);
if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
dx += src_x_off;
dy += src_y_off;
pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex);
glEnable(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glClientActiveTexture(GL_TEXTURE0);
glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glUseProgramObjectARB(glamor_priv->finish_access_prog[0]);
}
else {
GLAMOR_CHECK_PENDING_FILL(glamor_priv, src_pixmap_priv);
}
for (i = 0; i < nbox; i++) {
glamor_set_normalize_vcoords(dst_xscale, dst_yscale,
box[i].x1 + dst_x_off,
box[i].y1 + dst_y_off,
@ -273,11 +291,12 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
glamor_priv->yInverted,
vertices);
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);
if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv))
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);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
@ -285,8 +304,10 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
glUseProgramObjectARB(0);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_TEXTURE_2D);
if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_TEXTURE_2D);
}
return TRUE;
fail:
@ -352,6 +373,7 @@ glamor_copy_n_to_n(DrawablePtr src,
if (!temp_src)
goto fail;
glamor_transform_boxes(box, nbox, -bound.x1, -bound.y1);
temp_src = &temp_pixmap->drawable;
fbCopyNtoN(src, temp_src, gc, box, nbox,
temp_dx + bound.x1, temp_dy + bound.y1,
reverse, upsidedown, bitplane,
@ -359,7 +381,6 @@ glamor_copy_n_to_n(DrawablePtr src,
glamor_transform_boxes(box, nbox, bound.x1, bound.y1);
temp_dx = -bound.x1;
temp_dy = -bound.y1;
temp_src = &temp_pixmap->drawable;
}
else {
temp_dx = dx;

View File

@ -154,7 +154,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
GLfloat xscale, yscale;
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
glamor_fallback("dest has no fbo.\n");
glamor_fallback("dest %p has no fbo.\n", pixmap);
goto fail;
}
glamor_set_alu(alu);
@ -163,15 +163,29 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
goto fail;
}
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
glUseProgramObjectARB(glamor_priv->solid_prog);
glamor_get_rgba_from_pixel(fg_pixel,
&color[0],
&color[1],
&color[2],
&color[3],
format_for_pixmap(pixmap));
#ifdef GLAMOR_DELAYED_FILLING
if (x == 0 && y == 0
&& width == pixmap->drawable.width
&& height == pixmap->drawable.height
&& pixmap_priv->fb != glamor_priv->screen_fbo ) {
pixmap_priv->pending_op.type = GLAMOR_PENDING_FILL;
memcpy(&pixmap_priv->pending_op.fill.color4fv,
color, 4*sizeof(GLfloat));
pixmap_priv->pending_op.fill.colori = fg_pixel;
return TRUE;
}
#endif
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
glamor_validate_pixmap(pixmap);
glUseProgramObjectARB(glamor_priv->solid_prog);
glUniform4fvARB(glamor_priv->solid_color_uniform_location, 1, color);
glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);

View File

@ -64,6 +64,7 @@ glamor_get_spans(DrawablePtr drawable,
}
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
glamor_validate_pixmap(pixmap);
glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
for (i = 0; i < count; i++) {

View File

@ -26,14 +26,71 @@ glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap,
*y = 0;
}
static void
_glamor_pixmap_validate_filling(glamor_screen_private *glamor_priv,
glamor_pixmap_private *pixmap_priv)
{
GLfloat vertices[8];
// glamor_set_destination_pixmap_priv_nc(pixmap_priv);
glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glUseProgramObjectARB(glamor_priv->solid_prog);
glUniform4fvARB(glamor_priv->solid_color_uniform_location,
1, pixmap_priv->pending_op.fill.color4fv);
vertices[0] = -1;
vertices[1] = -1;
vertices[2] = 1;
vertices[3] = -1;
vertices[4] = 1;
vertices[5] = 1;
vertices[6] = -1;
vertices[7] = 1;
glDrawArrays(GL_QUADS, 0, 4);
glDisableClientState(GL_VERTEX_ARRAY);
glUseProgramObjectARB(0);
pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE;
}
glamor_pixmap_validate_function_t pixmap_validate_funcs[] = {
NULL,
_glamor_pixmap_validate_filling
};
void
glamor_pixmap_init(ScreenPtr screen)
{
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
glamor_priv->pixmap_validate_funcs = pixmap_validate_funcs;
}
void
glamor_validate_pixmap(PixmapPtr pixmap)
{
glamor_pixmap_validate_function_t validate_op;
glamor_screen_private *glamor_priv =
glamor_get_screen_private(pixmap->drawable.pScreen);
glamor_pixmap_private *pixmap_priv =
glamor_get_pixmap_private(pixmap);
validate_op = glamor_priv->pixmap_validate_funcs[pixmap_priv->pending_op.type];
if (validate_op) {
(*validate_op)(glamor_priv, pixmap_priv);
}
}
void
glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv)
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
glMatrixMode(GL_PROJECTION); glLoadIdentity();
glMatrixMode(GL_MODELVIEW); glLoadIdentity();
glViewport(0, 0,
pixmap_priv->container->drawable.width,
pixmap_priv->container->drawable.height);
}
int
@ -49,9 +106,11 @@ glamor_set_destination_pixmap_priv(glamor_pixmap_private *pixmap_priv)
int
glamor_set_destination_pixmap(PixmapPtr pixmap)
{
int err;
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
return glamor_set_destination_pixmap_priv(pixmap_priv);
err = glamor_set_destination_pixmap_priv(pixmap_priv);
return err;
}
Bool
@ -376,7 +435,8 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
return TRUE;
/* XXX we may don't need to validate it on GPU here,
* we can just validate it on CPU. */
if (glamor_get_tex_format_type_from_pixmap(pixmap,
&format,
&type,
@ -395,7 +455,8 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
pixmap->drawable.depth);
stride = pixmap->devKind;
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
glamor_validate_pixmap(pixmap);
switch (access) {
case GLAMOR_ACCESS_RO:
gl_access = GL_READ_ONLY_ARB;
@ -415,7 +476,6 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
}
row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_PACK_ROW_LENGTH, row_length);

View File

@ -149,6 +149,10 @@ enum shader_in {
SHADER_IN_COUNT,
};
struct glamor_screen_private;
struct glamor_pixmap_private;
typedef void (*glamor_pixmap_validate_function_t)(struct glamor_screen_private*,
struct glamor_pixmap_private*);
#define GLAMOR_CREATE_PIXMAP_CPU 0x100
typedef struct glamor_screen_private {
CloseScreenProcPtr saved_close_screen;
@ -197,7 +201,7 @@ typedef struct glamor_screen_private {
[SHADER_IN_COUNT];
Bool has_source_coords, has_mask_coords;
int render_nr_verts;
glamor_pixmap_validate_function_t *pixmap_validate_funcs;
glamor_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES];
char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1];
int delayed_fallback_pending;
@ -220,9 +224,34 @@ typedef enum glamor_access {
* @pbo: attached pbo.
* @access_mode: access mode during the prepare/finish pair.
* @pict_format: the corresponding picture's format.
* #pending_op: currently only support pending filling.
* @container: The corresponding pixmap's pointer.
**/
#define GLAMOR_PIXMAP_PRIV_NEED_VALIDATE(pixmap_priv) \
(GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) \
&& (pixmap_priv->pending_op.type != GLAMOR_PENDING_NONE))
#define GLAMOR_PIXMAP_PRIV_NO_PENDING(pixmap_priv) \
(pixmap_priv->pending_op.type == GLAMOR_PENDING_NONE)
enum _glamor_pending_op_type{
GLAMOR_PENDING_NONE,
GLAMOR_PENDING_FILL
};
typedef struct _glamor_pending_fill {
unsigned int type;
GLfloat color4fv[4];
CARD32 colori;
} glamor_pending_fill;
typedef union _glamor_pending_op {
unsigned int type;
glamor_pending_fill fill;
} glamor_pending_op;
typedef struct glamor_pixmap_private {
unsigned char gl_fbo:1;
unsigned char gl_tex:1;
@ -233,9 +262,20 @@ typedef struct glamor_pixmap_private {
GLuint pbo;
glamor_access_t access_mode;
PictFormatShort pict_format;
glamor_pending_op pending_op;
PixmapPtr container;
} glamor_pixmap_private;
#define GLAMOR_CHECK_PENDING_FILL(_glamor_priv_, _pixmap_priv_) do \
{ \
if (_pixmap_priv_->pending_op.type == GLAMOR_PENDING_FILL) { \
glUseProgramObjectARB(_glamor_priv_->solid_prog); \
glUniform4fvARB(_glamor_priv_->solid_color_uniform_location, 1, \
_pixmap_priv_->pending_op.fill.color4fv); \
} \
} while(0)
/*
* Pixmap dynamic status, used by dynamic upload feature.
*
@ -678,6 +718,8 @@ glamor_triangles (CARD8 op,
/* glamor_pixmap.c */
void
glamor_pixmap_init(ScreenPtr screen);
/**
* Download a pixmap's texture to cpu memory. If success,
* One copy of current pixmap's texture will be put into
@ -724,7 +766,8 @@ glamor_upload_picture_to_texture(PicturePtr picture);
void
glamor_destroy_upload_pixmap(PixmapPtr pixmap);
void
glamor_validate_pixmap(PixmapPtr pixmap);
int
glamor_create_picture(PicturePtr picture);
@ -753,6 +796,7 @@ glamor_picture_format_fixup(PicturePtr picture, glamor_pixmap_private *pixmap_pr
#define GLAMOR_PIXMAP_DYNAMIC_UPLOAD
#define GLAMOR_DELAYED_FILLING
#include"glamor_utils.h"

View File

@ -296,6 +296,8 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
}
/* XXX consider to reuse a function to do the following work. */
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
glamor_validate_pixmap(pixmap);
glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
glEnableClientState(GL_VERTEX_ARRAY);
@ -303,7 +305,6 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 /

View File

@ -395,16 +395,8 @@ glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture,
}
static void
glamor_set_composite_solid(PicturePtr picture, GLint uniform_location)
glamor_set_composite_solid(float *color, GLint uniform_location)
{
CARD32 c = picture->pSourcePict->solidFill.color; /* a8r8g8b8 */
float color[4]; /* rgba */
color[0] = ((c >> 16) & 0xff) / 255.0;
color[1] = ((c >> 8) & 0xff) / 255.0;
color[2] = ((c >> 0) & 0xff) / 255.0;
color[3] = ((c >> 24) & 0xff) / 255.0;
glUniform4fvARB(uniform_location, 1, color);
}
@ -696,6 +688,7 @@ glamor_composite_with_shader(CARD8 op,
enum glamor_pixmap_status mask_status = GLAMOR_NONE;
PictFormatShort saved_source_format = 0;
float src_matrix[9], mask_matrix[9];
GLfloat source_solid_color[4], mask_solid_color[4];
dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
@ -707,6 +700,12 @@ glamor_composite_with_shader(CARD8 op,
if (!source->pDrawable) {
if (source->pSourcePict->type == SourcePictTypeSolidFill) {
key.source = SHADER_SOURCE_SOLID;
glamor_get_rgba_from_pixel(source->pSourcePict->solidFill.color,
&source_solid_color[0],
&source_solid_color[1],
&source_solid_color[2],
&source_solid_color[3],
PICT_a8r8g8b8);
} else {
glamor_fallback("gradient source\n");
goto fail;
@ -718,6 +717,12 @@ glamor_composite_with_shader(CARD8 op,
if (!mask->pDrawable) {
if (mask->pSourcePict->type == SourcePictTypeSolidFill) {
key.mask = SHADER_MASK_SOLID;
glamor_get_rgba_from_pixel(mask->pSourcePict->solidFill.color,
&mask_solid_color[0],
&mask_solid_color[1],
&mask_solid_color[2],
&mask_solid_color[3],
PICT_a8r8g8b8);
} else {
glamor_fallback("gradient mask\n");
goto fail;
@ -767,6 +772,10 @@ glamor_composite_with_shader(CARD8 op,
glamor_fallback("no texture in source\n");
goto fail;
#endif
}
else if (source_pixmap_priv->pending_op.type == GLAMOR_PENDING_FILL) {
key.source = SHADER_SOURCE_SOLID;
memcpy(source_solid_color, source_pixmap_priv->pending_op.fill.color4fv, 4 * sizeof(float));
}
}
if (key.mask == SHADER_MASK_TEXTURE ||
@ -785,6 +794,10 @@ glamor_composite_with_shader(CARD8 op,
goto fail;
#endif
}
else if (mask_pixmap_priv->pending_op.type == GLAMOR_PENDING_FILL) {
key.mask = SHADER_MASK_SOLID;
memcpy(mask_solid_color, mask_pixmap_priv->pending_op.fill.color4fv, 4 * sizeof(float));
}
}
#ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
if (source_status == GLAMOR_UPLOAD_PENDING
@ -853,10 +866,11 @@ glamor_composite_with_shader(CARD8 op,
}
}
#endif
glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
glamor_validate_pixmap(dest_pixmap);
if (!glamor_set_composite_op(screen, op, dest, mask)) {
goto fail;
}
glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
shader = glamor_lookup_composite_shader(screen, &key);
if (shader->prog == 0) {
@ -866,13 +880,13 @@ glamor_composite_with_shader(CARD8 op,
glUseProgramObjectARB(shader->prog);
if (key.source == SHADER_SOURCE_SOLID) {
glamor_set_composite_solid(source, shader->source_uniform_location);
glamor_set_composite_solid(source_solid_color, shader->source_uniform_location);
} else {
glamor_set_composite_texture(screen, 0, source, source_pixmap_priv);
}
if (key.mask != SHADER_MASK_NONE) {
if (key.mask == SHADER_MASK_SOLID) {
glamor_set_composite_solid(mask, shader->mask_uniform_location);
glamor_set_composite_solid(mask_solid_color, shader->mask_uniform_location);
} else {
glamor_set_composite_texture(screen, 1, mask, mask_pixmap_priv);
}
@ -888,14 +902,14 @@ glamor_composite_with_shader(CARD8 op,
if (source_pixmap) {
if (glamor_priv->has_source_coords) {
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) {
if (glamor_priv->has_mask_coords) {
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);
@ -944,14 +958,14 @@ glamor_composite_with_shader(CARD8 op,
y_source += source_y_off;
x_mask += mask_x_off;
y_mask += mask_y_off;
box = REGION_RECTS(&region);
for (i = 0; i < REGION_NUM_RECTS(&region); i++) {
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_set_normalize_vcoords(dst_xscale, dst_yscale, vx1, vy1, vx2, vy2,
glamor_priv->yInverted, vertices);
if (key.source != SHADER_SOURCE_SOLID) {
@ -1260,7 +1274,7 @@ glamor_create_mask_picture(ScreenPtr screen,
pixmap = screen->CreatePixmap(screen, 0, 0,
pict_format->depth,
0);
GLAMOR_CREATE_PIXMAP_CPU);
if (!pixmap)
return 0;
picture = CreatePicture(0, &pixmap->drawable, pict_format,

View File

@ -52,9 +52,10 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
drawable->depth);
goto fail;
}
if (glamor_set_destination_pixmap(dest_pixmap))
goto fail;
glamor_validate_pixmap(dest_pixmap);
if (!glamor_set_planemask(dest_pixmap, gc->planemask))
goto fail;
glamor_set_alu(gc->alu);

View File

@ -107,7 +107,6 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
glamor_fallback("dest has no fbo.\n");
goto fail;
}
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) {
/* XXX dynamic uploading candidate. */
glamor_fallback("Non-texture tile pixmap\n");
@ -118,48 +117,59 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
glamor_fallback("unsupported planemask %lx\n", planemask);
goto fail;
}
if (alu != GXcopy) {
glamor_set_destination_pixmap_priv_nc(src_pixmap_priv);
glamor_validate_pixmap(tile);
}
glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
glamor_validate_pixmap(pixmap);
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, 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);
if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
glUseProgramObjectARB(glamor_priv->tile_prog);
glActiveTexture(GL_TEXTURE0);
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);
glamor_set_normalize_tcoords(src_xscale, src_yscale,
tile_x1, tile_y1,
tile_x2, tile_y2,
glamor_priv->yInverted,
source_texcoords);
glClientActiveTexture(GL_TEXTURE0);
glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, source_texcoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
else {
GLAMOR_CHECK_PENDING_FILL(glamor_priv, src_pixmap_priv);
}
glamor_set_normalize_vcoords(dst_xscale, dst_yscale,
x1, y1,x2, y2,
glamor_priv->yInverted,
vertices);
glamor_set_normalize_tcoords(src_xscale, src_yscale,
tile_x1, tile_y1,
tile_x2, tile_y2,
glamor_priv->yInverted,
source_texcoords);
glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glClientActiveTexture(GL_TEXTURE0);
glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, source_texcoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
glClientActiveTexture(GL_TEXTURE0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_TEXTURE_2D);
}
glDisableClientState(GL_VERTEX_ARRAY);
glUseProgramObjectARB(0);
glDisable(GL_TEXTURE_2D);
glamor_set_alu(GXcopy);
glamor_set_planemask(pixmap, ~0);
return TRUE;