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_set_pixmap_texture(pixmap, w, h, tex);
|
||||||
glamor_priv->screen_fbo = pixmap_priv->fb;
|
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)
|
if (w > 32767 || h > 32767)
|
||||||
return NullPixmap;
|
return NullPixmap;
|
||||||
|
|
||||||
if (!glamor_check_fbo_width_height(w,h)
|
if (!glamor_check_fbo_width_height(w,h)
|
||||||
|| !glamor_check_fbo_depth(depth)
|
|| !glamor_check_fbo_depth(depth)
|
||||||
|| usage == GLAMOR_CREATE_PIXMAP_CPU) {
|
|| usage == GLAMOR_CREATE_PIXMAP_CPU) {
|
||||||
/* MESA can only support upto MAX_WIDTH*MAX_HEIGHT fbo.
|
/* 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_fbo = 1;
|
||||||
pixmap_priv->gl_tex = 1;
|
pixmap_priv->gl_tex = 1;
|
||||||
pixmap_priv->container = pixmap;
|
pixmap_priv->container = pixmap;
|
||||||
|
pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE;
|
||||||
|
|
||||||
screen->CreatePixmap = glamor_create_pixmap;
|
screen->CreatePixmap = glamor_create_pixmap;
|
||||||
return pixmap;
|
return pixmap;
|
||||||
|
@ -369,6 +371,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
|
||||||
glamor_init_putimage_shaders(screen);
|
glamor_init_putimage_shaders(screen);
|
||||||
glamor_init_finish_access_shaders(screen);
|
glamor_init_finish_access_shaders(screen);
|
||||||
glamor_glyphs_init(screen);
|
glamor_glyphs_init(screen);
|
||||||
|
glamor_pixmap_init(screen);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,9 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
|
||||||
|
|
||||||
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
|
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) {
|
||||||
if (gc->alu != GXcopy) {
|
if (gc->alu != GXcopy) {
|
||||||
glamor_delayed_fallback(screen, "non-copy ALU\n");
|
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)) {
|
if (glamor_set_destination_pixmap(dst_pixmap)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
glamor_validate_pixmap(dst_pixmap);
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->fb);
|
glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->fb);
|
||||||
|
|
||||||
glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
|
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);
|
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
|
||||||
glamor_screen_private *glamor_priv =
|
glamor_screen_private *glamor_priv =
|
||||||
glamor_get_screen_private(screen);
|
glamor_get_screen_private(screen);
|
||||||
|
glamor_pixmap_private *pixmap_priv;
|
||||||
int x_off, y_off, i;
|
int x_off, y_off, i;
|
||||||
if (src != dst) {
|
if (src != dst) {
|
||||||
glamor_delayed_fallback(screen, "src != dest\n");
|
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)) {
|
if (glamor_set_destination_pixmap(dst_pixmap)) {
|
||||||
glamor_delayed_fallback(screen, "dst has no fbo.\n");
|
glamor_delayed_fallback(screen, "dst has no fbo.\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -234,37 +242,47 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
|
||||||
glamor_set_alu(gc->alu);
|
glamor_set_alu(gc->alu);
|
||||||
if (!glamor_set_planemask(dst_pixmap, gc->planemask))
|
if (!glamor_set_planemask(dst_pixmap, gc->planemask))
|
||||||
goto fail;
|
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_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(dst_pixmap_priv, &dst_xscale, &dst_yscale);
|
||||||
pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_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(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);
|
glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
|
||||||
glClientActiveTexture(GL_TEXTURE0);
|
if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
|
||||||
glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords);
|
glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
dx += src_x_off;
|
||||||
|
dy += src_y_off;
|
||||||
assert(GLEW_ARB_fragment_shader);
|
pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
|
||||||
glUseProgramObjectARB(glamor_priv->finish_access_prog[0]);
|
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++) {
|
for (i = 0; i < nbox; i++) {
|
||||||
|
|
||||||
glamor_set_normalize_vcoords(dst_xscale, dst_yscale,
|
glamor_set_normalize_vcoords(dst_xscale, dst_yscale,
|
||||||
box[i].x1 + dst_x_off,
|
box[i].x1 + dst_x_off,
|
||||||
box[i].y1 + dst_y_off,
|
box[i].y1 + dst_y_off,
|
||||||
|
@ -273,11 +291,12 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
|
||||||
glamor_priv->yInverted,
|
glamor_priv->yInverted,
|
||||||
vertices);
|
vertices);
|
||||||
|
|
||||||
glamor_set_normalize_tcoords(src_xscale, src_yscale,
|
if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv))
|
||||||
box[i].x1 + dx, box[i].y1 + dy,
|
glamor_set_normalize_tcoords(src_xscale, src_yscale,
|
||||||
box[i].x2 + dx, box[i].y2 + dy,
|
box[i].x1 + dx, box[i].y1 + dy,
|
||||||
glamor_priv->yInverted,
|
box[i].x2 + dx, box[i].y2 + dy,
|
||||||
texcoords);
|
glamor_priv->yInverted,
|
||||||
|
texcoords);
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||||
}
|
}
|
||||||
|
@ -285,8 +304,10 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
|
||||||
glUseProgramObjectARB(0);
|
glUseProgramObjectARB(0);
|
||||||
|
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
|
||||||
glDisable(GL_TEXTURE_2D);
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
@ -352,6 +373,7 @@ glamor_copy_n_to_n(DrawablePtr src,
|
||||||
if (!temp_src)
|
if (!temp_src)
|
||||||
goto fail;
|
goto fail;
|
||||||
glamor_transform_boxes(box, nbox, -bound.x1, -bound.y1);
|
glamor_transform_boxes(box, nbox, -bound.x1, -bound.y1);
|
||||||
|
temp_src = &temp_pixmap->drawable;
|
||||||
fbCopyNtoN(src, temp_src, gc, box, nbox,
|
fbCopyNtoN(src, temp_src, gc, box, nbox,
|
||||||
temp_dx + bound.x1, temp_dy + bound.y1,
|
temp_dx + bound.x1, temp_dy + bound.y1,
|
||||||
reverse, upsidedown, bitplane,
|
reverse, upsidedown, bitplane,
|
||||||
|
@ -359,7 +381,6 @@ glamor_copy_n_to_n(DrawablePtr src,
|
||||||
glamor_transform_boxes(box, nbox, bound.x1, bound.y1);
|
glamor_transform_boxes(box, nbox, bound.x1, bound.y1);
|
||||||
temp_dx = -bound.x1;
|
temp_dx = -bound.x1;
|
||||||
temp_dy = -bound.y1;
|
temp_dy = -bound.y1;
|
||||||
temp_src = &temp_pixmap->drawable;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
temp_dx = dx;
|
temp_dx = dx;
|
||||||
|
|
|
@ -154,7 +154,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
|
||||||
GLfloat xscale, yscale;
|
GLfloat xscale, yscale;
|
||||||
|
|
||||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
|
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;
|
goto fail;
|
||||||
}
|
}
|
||||||
glamor_set_alu(alu);
|
glamor_set_alu(alu);
|
||||||
|
@ -163,15 +163,29 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
|
|
||||||
|
|
||||||
glUseProgramObjectARB(glamor_priv->solid_prog);
|
|
||||||
glamor_get_rgba_from_pixel(fg_pixel,
|
glamor_get_rgba_from_pixel(fg_pixel,
|
||||||
&color[0],
|
&color[0],
|
||||||
&color[1],
|
&color[1],
|
||||||
&color[2],
|
&color[2],
|
||||||
&color[3],
|
&color[3],
|
||||||
format_for_pixmap(pixmap));
|
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);
|
glUniform4fvARB(glamor_priv->solid_color_uniform_location, 1, color);
|
||||||
|
|
||||||
glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
|
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_set_destination_pixmap_priv_nc(pixmap_priv);
|
||||||
|
glamor_validate_pixmap(pixmap);
|
||||||
|
|
||||||
glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
|
glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
|
|
|
@ -26,14 +26,71 @@ glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap,
|
||||||
*y = 0;
|
*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
|
void
|
||||||
glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv)
|
glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv)
|
||||||
{
|
{
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
|
||||||
|
glMatrixMode(GL_PROJECTION); glLoadIdentity();
|
||||||
|
glMatrixMode(GL_MODELVIEW); glLoadIdentity();
|
||||||
|
|
||||||
glViewport(0, 0,
|
glViewport(0, 0,
|
||||||
pixmap_priv->container->drawable.width,
|
pixmap_priv->container->drawable.width,
|
||||||
pixmap_priv->container->drawable.height);
|
pixmap_priv->container->drawable.height);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -49,9 +106,11 @@ glamor_set_destination_pixmap_priv(glamor_pixmap_private *pixmap_priv)
|
||||||
int
|
int
|
||||||
glamor_set_destination_pixmap(PixmapPtr pixmap)
|
glamor_set_destination_pixmap(PixmapPtr pixmap)
|
||||||
{
|
{
|
||||||
|
int err;
|
||||||
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
|
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
|
Bool
|
||||||
|
@ -376,7 +435,8 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
|
||||||
|
|
||||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
||||||
return TRUE;
|
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,
|
if (glamor_get_tex_format_type_from_pixmap(pixmap,
|
||||||
&format,
|
&format,
|
||||||
&type,
|
&type,
|
||||||
|
@ -395,7 +455,8 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
|
||||||
pixmap->drawable.depth);
|
pixmap->drawable.depth);
|
||||||
|
|
||||||
stride = pixmap->devKind;
|
stride = pixmap->devKind;
|
||||||
|
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
|
||||||
|
glamor_validate_pixmap(pixmap);
|
||||||
switch (access) {
|
switch (access) {
|
||||||
case GLAMOR_ACCESS_RO:
|
case GLAMOR_ACCESS_RO:
|
||||||
gl_access = GL_READ_ONLY_ARB;
|
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;
|
row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
|
|
||||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||||
glPixelStorei(GL_PACK_ROW_LENGTH, row_length);
|
glPixelStorei(GL_PACK_ROW_LENGTH, row_length);
|
||||||
|
|
||||||
|
|
|
@ -149,6 +149,10 @@ enum shader_in {
|
||||||
SHADER_IN_COUNT,
|
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
|
#define GLAMOR_CREATE_PIXMAP_CPU 0x100
|
||||||
typedef struct glamor_screen_private {
|
typedef struct glamor_screen_private {
|
||||||
CloseScreenProcPtr saved_close_screen;
|
CloseScreenProcPtr saved_close_screen;
|
||||||
|
@ -197,7 +201,7 @@ typedef struct glamor_screen_private {
|
||||||
[SHADER_IN_COUNT];
|
[SHADER_IN_COUNT];
|
||||||
Bool has_source_coords, has_mask_coords;
|
Bool has_source_coords, has_mask_coords;
|
||||||
int render_nr_verts;
|
int render_nr_verts;
|
||||||
|
glamor_pixmap_validate_function_t *pixmap_validate_funcs;
|
||||||
glamor_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES];
|
glamor_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES];
|
||||||
char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1];
|
char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1];
|
||||||
int delayed_fallback_pending;
|
int delayed_fallback_pending;
|
||||||
|
@ -220,9 +224,34 @@ typedef enum glamor_access {
|
||||||
* @pbo: attached pbo.
|
* @pbo: attached pbo.
|
||||||
* @access_mode: access mode during the prepare/finish pair.
|
* @access_mode: access mode during the prepare/finish pair.
|
||||||
* @pict_format: the corresponding picture's format.
|
* @pict_format: the corresponding picture's format.
|
||||||
|
* #pending_op: currently only support pending filling.
|
||||||
* @container: The corresponding pixmap's pointer.
|
* @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 {
|
typedef struct glamor_pixmap_private {
|
||||||
unsigned char gl_fbo:1;
|
unsigned char gl_fbo:1;
|
||||||
unsigned char gl_tex:1;
|
unsigned char gl_tex:1;
|
||||||
|
@ -233,9 +262,20 @@ typedef struct glamor_pixmap_private {
|
||||||
GLuint pbo;
|
GLuint pbo;
|
||||||
glamor_access_t access_mode;
|
glamor_access_t access_mode;
|
||||||
PictFormatShort pict_format;
|
PictFormatShort pict_format;
|
||||||
|
glamor_pending_op pending_op;
|
||||||
PixmapPtr container;
|
PixmapPtr container;
|
||||||
} glamor_pixmap_private;
|
} 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.
|
* Pixmap dynamic status, used by dynamic upload feature.
|
||||||
*
|
*
|
||||||
|
@ -678,6 +718,8 @@ glamor_triangles (CARD8 op,
|
||||||
|
|
||||||
/* glamor_pixmap.c */
|
/* glamor_pixmap.c */
|
||||||
|
|
||||||
|
void
|
||||||
|
glamor_pixmap_init(ScreenPtr screen);
|
||||||
/**
|
/**
|
||||||
* Download a pixmap's texture to cpu memory. If success,
|
* Download a pixmap's texture to cpu memory. If success,
|
||||||
* One copy of current pixmap's texture will be put into
|
* One copy of current pixmap's texture will be put into
|
||||||
|
@ -724,7 +766,8 @@ glamor_upload_picture_to_texture(PicturePtr picture);
|
||||||
void
|
void
|
||||||
glamor_destroy_upload_pixmap(PixmapPtr pixmap);
|
glamor_destroy_upload_pixmap(PixmapPtr pixmap);
|
||||||
|
|
||||||
|
void
|
||||||
|
glamor_validate_pixmap(PixmapPtr pixmap);
|
||||||
|
|
||||||
int
|
int
|
||||||
glamor_create_picture(PicturePtr picture);
|
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_PIXMAP_DYNAMIC_UPLOAD
|
||||||
|
#define GLAMOR_DELAYED_FILLING
|
||||||
|
|
||||||
|
|
||||||
#include"glamor_utils.h"
|
#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. */
|
/* 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);
|
glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
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);
|
glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords);
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
|
||||||
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
|
|
||||||
|
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 /
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 /
|
||||||
|
|
|
@ -395,16 +395,8 @@ glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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);
|
glUniform4fvARB(uniform_location, 1, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -696,6 +688,7 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
enum glamor_pixmap_status mask_status = GLAMOR_NONE;
|
enum glamor_pixmap_status mask_status = GLAMOR_NONE;
|
||||||
PictFormatShort saved_source_format = 0;
|
PictFormatShort saved_source_format = 0;
|
||||||
float src_matrix[9], mask_matrix[9];
|
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);
|
dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
|
||||||
|
|
||||||
|
@ -707,6 +700,12 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
if (!source->pDrawable) {
|
if (!source->pDrawable) {
|
||||||
if (source->pSourcePict->type == SourcePictTypeSolidFill) {
|
if (source->pSourcePict->type == SourcePictTypeSolidFill) {
|
||||||
key.source = SHADER_SOURCE_SOLID;
|
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 {
|
} else {
|
||||||
glamor_fallback("gradient source\n");
|
glamor_fallback("gradient source\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -718,6 +717,12 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
if (!mask->pDrawable) {
|
if (!mask->pDrawable) {
|
||||||
if (mask->pSourcePict->type == SourcePictTypeSolidFill) {
|
if (mask->pSourcePict->type == SourcePictTypeSolidFill) {
|
||||||
key.mask = SHADER_MASK_SOLID;
|
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 {
|
} else {
|
||||||
glamor_fallback("gradient mask\n");
|
glamor_fallback("gradient mask\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -767,6 +772,10 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
glamor_fallback("no texture in source\n");
|
glamor_fallback("no texture in source\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
#endif
|
#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 ||
|
if (key.mask == SHADER_MASK_TEXTURE ||
|
||||||
|
@ -785,6 +794,10 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
goto fail;
|
goto fail;
|
||||||
#endif
|
#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
|
#ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
|
||||||
if (source_status == GLAMOR_UPLOAD_PENDING
|
if (source_status == GLAMOR_UPLOAD_PENDING
|
||||||
|
@ -853,10 +866,11 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
|
||||||
|
glamor_validate_pixmap(dest_pixmap);
|
||||||
if (!glamor_set_composite_op(screen, op, dest, mask)) {
|
if (!glamor_set_composite_op(screen, op, dest, mask)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
|
|
||||||
|
|
||||||
shader = glamor_lookup_composite_shader(screen, &key);
|
shader = glamor_lookup_composite_shader(screen, &key);
|
||||||
if (shader->prog == 0) {
|
if (shader->prog == 0) {
|
||||||
|
@ -866,13 +880,13 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
|
|
||||||
glUseProgramObjectARB(shader->prog);
|
glUseProgramObjectARB(shader->prog);
|
||||||
if (key.source == SHADER_SOURCE_SOLID) {
|
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 {
|
} else {
|
||||||
glamor_set_composite_texture(screen, 0, source, source_pixmap_priv);
|
glamor_set_composite_texture(screen, 0, source, source_pixmap_priv);
|
||||||
}
|
}
|
||||||
if (key.mask != SHADER_MASK_NONE) {
|
if (key.mask != SHADER_MASK_NONE) {
|
||||||
if (key.mask == SHADER_MASK_SOLID) {
|
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 {
|
} else {
|
||||||
glamor_set_composite_texture(screen, 1, mask, mask_pixmap_priv);
|
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,
|
glamor_get_drawable_deltas(source->pDrawable, source_pixmap,
|
||||||
&source_x_off, &source_y_off);
|
&source_x_off, &source_y_off);
|
||||||
pixmap_priv_get_scale(source_pixmap_priv, &src_xscale, &src_yscale);
|
pixmap_priv_get_scale(source_pixmap_priv, &src_xscale, &src_yscale);
|
||||||
glamor_picture_get_matrixf(source, src_matrix);
|
glamor_picture_get_matrixf(source, src_matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask_pixmap) {
|
if (glamor_priv->has_mask_coords) {
|
||||||
glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap,
|
glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap,
|
||||||
&mask_x_off, &mask_y_off);
|
&mask_x_off, &mask_y_off);
|
||||||
pixmap_priv_get_scale(mask_pixmap_priv, &mask_xscale, &mask_yscale);
|
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;
|
y_source += source_y_off;
|
||||||
x_mask += mask_x_off;
|
x_mask += mask_x_off;
|
||||||
y_mask += mask_y_off;
|
y_mask += mask_y_off;
|
||||||
|
|
||||||
box = REGION_RECTS(®ion);
|
box = REGION_RECTS(®ion);
|
||||||
for (i = 0; i < REGION_NUM_RECTS(®ion); i++) {
|
for (i = 0; i < REGION_NUM_RECTS(®ion); i++) {
|
||||||
int vx1 = box[i].x1 + dest_x_off;
|
int vx1 = box[i].x1 + dest_x_off;
|
||||||
int vx2 = box[i].x2 + dest_x_off;
|
int vx2 = box[i].x2 + dest_x_off;
|
||||||
int vy1 = box[i].y1 + dest_y_off;
|
int vy1 = box[i].y1 + dest_y_off;
|
||||||
int vy2 = box[i].y2 + 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);
|
glamor_priv->yInverted, vertices);
|
||||||
|
|
||||||
if (key.source != SHADER_SOURCE_SOLID) {
|
if (key.source != SHADER_SOURCE_SOLID) {
|
||||||
|
@ -1260,7 +1274,7 @@ glamor_create_mask_picture(ScreenPtr screen,
|
||||||
|
|
||||||
pixmap = screen->CreatePixmap(screen, 0, 0,
|
pixmap = screen->CreatePixmap(screen, 0, 0,
|
||||||
pict_format->depth,
|
pict_format->depth,
|
||||||
0);
|
GLAMOR_CREATE_PIXMAP_CPU);
|
||||||
if (!pixmap)
|
if (!pixmap)
|
||||||
return 0;
|
return 0;
|
||||||
picture = CreatePicture(0, &pixmap->drawable, pict_format,
|
picture = CreatePicture(0, &pixmap->drawable, pict_format,
|
||||||
|
|
|
@ -52,9 +52,10 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
|
||||||
drawable->depth);
|
drawable->depth);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (glamor_set_destination_pixmap(dest_pixmap))
|
if (glamor_set_destination_pixmap(dest_pixmap))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
glamor_validate_pixmap(dest_pixmap);
|
||||||
if (!glamor_set_planemask(dest_pixmap, gc->planemask))
|
if (!glamor_set_planemask(dest_pixmap, gc->planemask))
|
||||||
goto fail;
|
goto fail;
|
||||||
glamor_set_alu(gc->alu);
|
glamor_set_alu(gc->alu);
|
||||||
|
|
|
@ -107,7 +107,6 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
|
||||||
glamor_fallback("dest has no fbo.\n");
|
glamor_fallback("dest has no fbo.\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) {
|
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) {
|
||||||
/* XXX dynamic uploading candidate. */
|
/* XXX dynamic uploading candidate. */
|
||||||
glamor_fallback("Non-texture tile pixmap\n");
|
glamor_fallback("Non-texture tile pixmap\n");
|
||||||
|
@ -118,48 +117,59 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
|
||||||
glamor_fallback("unsupported planemask %lx\n", planemask);
|
glamor_fallback("unsupported planemask %lx\n", planemask);
|
||||||
goto fail;
|
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_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(dst_pixmap_priv, &dst_xscale, &dst_yscale);
|
||||||
pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
|
|
||||||
|
|
||||||
glamor_set_alu(alu);
|
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,
|
glamor_set_normalize_vcoords(dst_xscale, dst_yscale,
|
||||||
x1, y1,x2, y2,
|
x1, y1,x2, y2,
|
||||||
glamor_priv->yInverted,
|
glamor_priv->yInverted,
|
||||||
vertices);
|
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);
|
glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
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);
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||||
|
|
||||||
|
if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
|
||||||
glClientActiveTexture(GL_TEXTURE0);
|
glClientActiveTexture(GL_TEXTURE0);
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
|
|
||||||
glUseProgramObjectARB(0);
|
glUseProgramObjectARB(0);
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
glamor_set_alu(GXcopy);
|
glamor_set_alu(GXcopy);
|
||||||
glamor_set_planemask(pixmap, ~0);
|
glamor_set_planemask(pixmap, ~0);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user