diff --git a/glamor/glamor.c b/glamor/glamor.c index 2eec6f536..695230885 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -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; diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index 9e2be123e..4cbb3c66b 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -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; diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index a41837b3a..393f651ed 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -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); diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c index 7fe05f993..237c1e789 100644 --- a/glamor/glamor_getspans.c +++ b/glamor/glamor_getspans.c @@ -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++) { diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index c76920a26..924a17369 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -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); diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 4b0037333..b7fcfbdeb 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -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" diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index e61425d11..0a910509c 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -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 / diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 41ee46b7d..f0a6e880c 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -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(®ion); for (i = 0; i < REGION_NUM_RECTS(®ion); 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, diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c index 9bc7d1567..14a24378f 100644 --- a/glamor/glamor_setspans.c +++ b/glamor/glamor_setspans.c @@ -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); diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c index 5bfdd7341..a78c30194 100644 --- a/glamor/glamor_tile.c +++ b/glamor/glamor_tile.c @@ -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;