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:
parent
1caf741a4a
commit
5c4d53c512
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
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);
|
||||
|
||||
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]);
|
||||
|
||||
}
|
||||
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,6 +291,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
|
|||
glamor_priv->yInverted,
|
||||
vertices);
|
||||
|
||||
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,
|
||||
|
@ -285,8 +304,10 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
|
|||
glUseProgramObjectARB(0);
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 /
|
||||
|
|
|
@ -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;
|
||||
|
@ -768,6 +773,10 @@ glamor_composite_with_shader(CARD8 op,
|
|||
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 ||
|
||||
key.mask == SHADER_MASK_TEXTURE_ALPHA) {
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,12 +117,19 @@ 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);
|
||||
|
||||
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);
|
||||
|
@ -133,33 +139,37 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
|
|||
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;
|
||||
|
|
Loading…
Reference in New Issue
Block a user