glamor: Fix up and enable accelerated composite.

This commit is contained in:
Eric Anholt 2010-02-09 22:54:40 -06:00 committed by Zhigang Gong
parent a0b589e90a
commit 7e6432e7b9
3 changed files with 249 additions and 163 deletions

View File

@ -32,30 +32,6 @@
* GC CopyArea implementation * GC CopyArea implementation
*/ */
static float
v_from_x_coord_x(PixmapPtr pixmap, int x)
{
return (float)(x - pixmap->screen_x) / pixmap->drawable.width * 2.0 - 1.0;
}
static float
v_from_x_coord_y(PixmapPtr pixmap, int y)
{
return (float)(y - pixmap->screen_y) / pixmap->drawable.height * -2.0 + 1.0;
}
static float
t_from_x_coord_x(PixmapPtr pixmap, int x)
{
return (float)(x - pixmap->screen_x) / pixmap->drawable.width;
}
static float
t_from_x_coord_y(PixmapPtr pixmap, int y)
{
return 1.0 - (float)(y - pixmap->screen_y) / pixmap->drawable.height;
}
void void
glamor_copy_n_to_n(DrawablePtr src, glamor_copy_n_to_n(DrawablePtr src,
DrawablePtr dst, DrawablePtr dst,
@ -175,10 +151,12 @@ RegionPtr
glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
int srcx, int srcy, int width, int height, int dstx, int dsty) int srcx, int srcy, int width, int height, int dstx, int dsty)
{ {
#if 0
ScreenPtr screen = dst->pScreen; ScreenPtr screen = dst->pScreen;
PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap); glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap);
#endif
RegionPtr region; RegionPtr region;
region = miDoCopy(src, dst, gc, region = miDoCopy(src, dst, gc,
@ -187,6 +165,7 @@ glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
return region; return region;
#if 0
fail: fail:
glamor_fallback("glamor_copy_area from %p to %p (%c,%c)\n", src, dst, glamor_fallback("glamor_copy_area from %p to %p (%c,%c)\n", src, dst,
glamor_get_drawable_location(src), glamor_get_drawable_location(src),
@ -201,4 +180,5 @@ fail:
glamor_finish_access(dst); glamor_finish_access(dst);
} }
return region; return region;
#endif
} }

View File

@ -132,6 +132,30 @@ glamor_fallback(char *format, ...)
va_end(ap); va_end(ap);
} }
static inline float
v_from_x_coord_x(PixmapPtr pixmap, int x)
{
return (float)(x - pixmap->screen_x) / pixmap->drawable.width * 2.0 - 1.0;
}
static inline float
v_from_x_coord_y(PixmapPtr pixmap, int y)
{
return (float)(y - pixmap->screen_y) / pixmap->drawable.height * -2.0 + 1.0;
}
static inline float
t_from_x_coord_x(PixmapPtr pixmap, int x)
{
return (float)(x - pixmap->screen_x) / pixmap->drawable.width;
}
static inline float
t_from_x_coord_y(PixmapPtr pixmap, int y)
{
return 1.0 - (float)(y - pixmap->screen_y) / pixmap->drawable.height;
}
/* glamor.c */ /* glamor.c */
PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable); PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable);

View File

@ -94,23 +94,20 @@ static GLuint
glamor_create_composite_fs(struct shader_key *key) glamor_create_composite_fs(struct shader_key *key)
{ {
const char *source_pixmap_header = const char *source_pixmap_header =
"uniform sampler2D source_sampler;\n" "uniform sampler2D source_sampler;\n";
"varying vec4 source_coords;\n";
const char *source_solid_header = const char *source_solid_header =
"uniform vec4 source;\n"; "uniform vec4 source;\n";
const char *mask_pixmap_header = const char *mask_pixmap_header =
"uniform sampler2D mask_sampler;\n" "uniform sampler2D mask_sampler;\n";
"varying vec4 mask_coords;\n";
const char *mask_solid_header = const char *mask_solid_header =
"uniform vec4 mask;\n"; "uniform vec4 mask;\n";
const char *main_opening = const char *main_opening =
"void main()\n" "void main()\n"
"{\n"; "{\n";
const char *source_pixmap_fetch = const char *source_pixmap_fetch =
" vec4 source = texture2DProj(source_sampler, " " vec4 source = texture2D(source_sampler, gl_TexCoord[0].xy);\n";
" source_coords.xyw);\n";
const char *mask_pixmap_fetch = const char *mask_pixmap_fetch =
" vec4 mask = texture2DProj(mask_sampler, mask_coords.xyw);\n"; " vec4 mask = texture2D(mask_sampler, gl_TexCoord[1].xy);\n";
const char *source_in_mask = const char *source_in_mask =
" gl_FragColor = source * mask.w;\n"; " gl_FragColor = source * mask.w;\n";
const char *source_only = const char *source_only =
@ -156,30 +153,20 @@ glamor_create_composite_fs(struct shader_key *key)
static GLuint static GLuint
glamor_create_composite_vs(struct shader_key *key) glamor_create_composite_vs(struct shader_key *key)
{ {
const char *header =
"uniform mat4 dest_to_dest;\n"
"uniform mat4 dest_to_source;\n"
"varying vec4 source_coords;\n";
const char *mask_header =
"uniform mat4 dest_to_mask;\n"
"varying vec4 mask_coords;\n";
const char *main_opening = const char *main_opening =
"void main()\n" "void main()\n"
"{\n" "{\n"
" vec4 incoming_dest_coords = vec4(gl_Vertex.xy, 0, 1);\n" " gl_Position = gl_Vertex;\n"
" gl_Position = dest_to_dest * incoming_dest_coords;\n" " gl_TexCoord[0] = gl_MultiTexCoord0;\n";
" source_coords = dest_to_source * incoming_dest_coords;\n";
const char *mask_coords = const char *mask_coords =
" mask_coords = dest_to_mask * incoming_dest_coords;\n"; " gl_TexCoord[1] = gl_MultiTexCoord1;\n";
const char *main_closing = const char *main_closing =
"}\n"; "}\n";
char *source; char *source;
GLuint prog; GLuint prog;
Bool compute_mask_coords = key->has_mask && !key->solid_mask; Bool compute_mask_coords = key->has_mask && !key->solid_mask;
source = XNFprintf("%s%s%s%s%s", source = XNFprintf("%s%s%s",
header,
compute_mask_coords ? mask_header : "",
main_opening, main_opening,
compute_mask_coords ? mask_coords : "", compute_mask_coords ? mask_coords : "",
main_closing); main_closing);
@ -214,8 +201,6 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key)
shader->prog = prog; shader->prog = prog;
glUseProgramObjectARB(prog); glUseProgramObjectARB(prog);
shader->dest_to_dest_uniform_location =
glGetUniformLocationARB(prog, "dest_to_dest");
if (key->solid_source) { if (key->solid_source) {
shader->source_uniform_location = glGetUniformLocationARB(prog, shader->source_uniform_location = glGetUniformLocationARB(prog,
@ -223,8 +208,6 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key)
} else { } else {
source_sampler_uniform_location = glGetUniformLocationARB(prog, source_sampler_uniform_location = glGetUniformLocationARB(prog,
"source_sampler"); "source_sampler");
shader->dest_to_source_uniform_location =
glGetUniformLocationARB(prog, "dest_to_source");
glUniform1i(source_sampler_uniform_location, 0); glUniform1i(source_sampler_uniform_location, 0);
} }
@ -236,8 +219,6 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key)
mask_sampler_uniform_location = glGetUniformLocationARB(prog, mask_sampler_uniform_location = glGetUniformLocationARB(prog,
"mask_sampler"); "mask_sampler");
glUniform1i(mask_sampler_uniform_location, 1); glUniform1i(mask_sampler_uniform_location, 1);
shader->dest_to_mask_uniform_location =
glGetUniformLocationARB(prog, "dest_to_mask");
} }
} }
} }
@ -255,6 +236,7 @@ glamor_init_composite_shaders(ScreenPtr screen)
key.solid_mask = TRUE; key.solid_mask = TRUE;
glamor_create_composite_shader(screen, &key); glamor_create_composite_shader(screen, &key);
memset(&key, 0, sizeof(key));
key.solid_source = TRUE; key.solid_source = TRUE;
key.has_mask = FALSE; key.has_mask = FALSE;
glamor_create_composite_shader(screen, &key); glamor_create_composite_shader(screen, &key);
@ -264,24 +246,6 @@ glamor_init_composite_shaders(ScreenPtr screen)
glamor_create_composite_shader(screen, &key); glamor_create_composite_shader(screen, &key);
} }
static void
glamor_set_composite_transform_matrix(GLUmat4 *m,
PicturePtr picture,
float x_source,
float y_source)
{
GLUmat4 temp;
DrawablePtr drawable = picture->pDrawable;
GLUvec4 scale = {{1.0f / drawable->width,
1.0f / drawable->height,
1.0,
1.0}};
gluTranslate3f(m, -x_source, -y_source, 0.0);
gluScale4v(&temp, &scale);
gluMult4m_4m(m, &temp, m);
}
static Bool static Bool
glamor_set_composite_op(ScreenPtr screen, glamor_set_composite_op(ScreenPtr screen,
CARD8 op, PicturePtr dest, PicturePtr mask) CARD8 op, PicturePtr dest, PicturePtr mask)
@ -298,10 +262,6 @@ glamor_set_composite_op(ScreenPtr screen,
source_blend = op_info->source_blend; source_blend = op_info->source_blend;
dest_blend = op_info->dest_blend; dest_blend = op_info->dest_blend;
if (mask && mask->componentAlpha && PICT_FORMAT_RGB(mask->format) != 0 &&
op_info->source_alpha && source_blend != GL_ZERO) {
}
/* If there's no dst alpha channel, adjust the blend op so that we'll treat /* If there's no dst alpha channel, adjust the blend op so that we'll treat
* it as always 1. * it as always 1.
*/ */
@ -336,12 +296,8 @@ glamor_set_composite_op(ScreenPtr screen,
static void static void
glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture, glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture,
glamor_pixmap_private *pixmap_priv, glamor_pixmap_private *pixmap_priv)
GLint transform_uniform_location,
int x_translate, int y_translate)
{ {
GLUmat4 transform;
glActiveTexture(GL_TEXTURE0 + unit); glActiveTexture(GL_TEXTURE0 + unit);
glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex); glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
switch (picture->repeatType) { switch (picture->repeatType) {
@ -376,13 +332,6 @@ glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture,
} }
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
glamor_set_composite_transform_matrix(&transform,
picture,
x_translate,
y_translate);
glUniformMatrix4fvARB(transform_uniform_location, 1, 0,
(float *)&transform);
} }
static void static void
@ -447,15 +396,15 @@ glamor_get_picture_location(PicturePtr picture)
} }
static Bool static Bool
glamor_composite_copy(CARD8 op, glamor_composite_with_copy(CARD8 op,
PicturePtr source, PicturePtr source,
PicturePtr dest, PicturePtr dest,
INT16 x_source, INT16 x_source,
INT16 y_source, INT16 y_source,
INT16 x_dest, INT16 x_dest,
INT16 y_dest, INT16 y_dest,
CARD16 width, CARD16 width,
CARD16 height) CARD16 height)
{ {
RegionRec region; RegionRec region;
@ -489,19 +438,59 @@ glamor_composite_copy(CARD8 op,
return TRUE; return TRUE;
} }
void static Bool
glamor_composite(CARD8 op, good_source_format(PicturePtr picture)
PicturePtr source, {
PicturePtr mask, switch (picture->format) {
PicturePtr dest, case PICT_a8:
INT16 x_source, case PICT_a8r8g8b8:
INT16 y_source, return TRUE;
INT16 x_mask, default:
INT16 y_mask, glamor_fallback("Bad source format 0x%08x\n", picture->format);
INT16 x_dest, return FALSE;
INT16 y_dest, }
CARD16 width, }
CARD16 height)
static Bool
good_mask_format(PicturePtr picture)
{
switch (picture->format) {
case PICT_a8:
case PICT_a8r8g8b8:
return TRUE;
default:
glamor_fallback("Bad mask format 0x%08x\n", picture->format);
return FALSE;
}
}
static Bool
good_dest_format(PicturePtr picture)
{
switch (picture->format) {
case PICT_a8:
case PICT_a8r8g8b8:
case PICT_x8r8g8b8:
return TRUE;
default:
glamor_fallback("Bad dest format 0x%08x\n", picture->format);
return FALSE;
}
}
static Bool
glamor_composite_with_shader(CARD8 op,
PicturePtr source,
PicturePtr mask,
PicturePtr dest,
INT16 x_source,
INT16 y_source,
INT16 x_mask,
INT16 y_mask,
INT16 x_dest,
INT16 y_dest,
CARD16 width,
CARD16 height)
{ {
ScreenPtr screen = dest->pDrawable->pScreen; ScreenPtr screen = dest->pDrawable->pScreen;
PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable); PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable);
@ -510,38 +499,10 @@ glamor_composite(CARD8 op,
glamor_pixmap_private *mask_pixmap_priv = NULL; glamor_pixmap_private *mask_pixmap_priv = NULL;
struct shader_key key; struct shader_key key;
glamor_composite_shader *shader; glamor_composite_shader *shader;
GLUmat4 dest_to_dest;
RegionRec region; RegionRec region;
float vertices[4][2], source_texcoords[4][2], mask_texcoords[4][2];
int i; int i;
BoxPtr box;
/* Do two-pass PictOpOver componentAlpha, until we enable
* dual source color blending.
*/
if (mask && mask->componentAlpha && op == PictOpOver) {
glamor_composite(PictOpOutReverse,
source, mask, dest,
x_source, y_source,
x_mask, y_mask,
x_dest, y_dest,
width, height);
glamor_composite(PictOpAdd,
source, mask, dest,
x_source, y_source,
x_mask, y_mask,
x_dest, y_dest,
width, height);
return;
}
if (!mask) {
if (glamor_composite_copy(op, source, dest,
x_source, y_source,
x_dest, y_dest,
width, height))
return;
}
goto fail;
memset(&key, 0, sizeof(key)); memset(&key, 0, sizeof(key));
key.has_mask = (mask != NULL); key.has_mask = (mask != NULL);
@ -581,6 +542,8 @@ glamor_composite(CARD8 op,
glamor_fallback("glamor_composite(): no FBO in source\n"); glamor_fallback("glamor_composite(): no FBO in source\n");
goto fail; goto fail;
} }
if (!good_source_format(source))
goto fail;
} }
if (mask && !key.solid_mask) { if (mask && !key.solid_mask) {
mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable); mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
@ -593,7 +556,11 @@ glamor_composite(CARD8 op,
glamor_fallback("glamor_composite(): no FBO in mask\n"); glamor_fallback("glamor_composite(): no FBO in mask\n");
goto fail; goto fail;
} }
if (!good_mask_format(mask))
goto fail;
} }
if (!good_dest_format(dest))
goto fail;
shader = glamor_lookup_composite_shader(screen, &key); shader = glamor_lookup_composite_shader(screen, &key);
if (shader->prog == 0) { if (shader->prog == 0) {
@ -622,27 +589,16 @@ glamor_composite(CARD8 op,
y_mask += mask->pDrawable->y; y_mask += mask->pDrawable->y;
} }
gluOrtho6f(&dest_to_dest,
dest_pixmap->screen_x, dest_pixmap->screen_x + width,
dest_pixmap->screen_y, dest_pixmap->screen_y + height,
-1, 1);
glUniformMatrix4fvARB(shader->dest_to_dest_uniform_location, 1, 0,
(float *)&dest_to_dest);
if (key.solid_source) { if (key.solid_source) {
glamor_set_composite_solid(source, shader->source_uniform_location); glamor_set_composite_solid(source, 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);
shader->dest_to_source_uniform_location,
x_source - x_dest, y_source - y_dest);
} }
if (key.has_mask) { if (key.has_mask) {
if (key.solid_mask) { if (key.solid_mask) {
glamor_set_composite_solid(mask, shader->mask_uniform_location); glamor_set_composite_solid(mask, 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);
shader->dest_to_mask_uniform_location,
x_mask - x_dest, y_mask - y_dest);
} }
} }
@ -652,25 +608,150 @@ glamor_composite(CARD8 op,
x_mask, y_mask, x_mask, y_mask,
x_dest, y_dest, x_dest, y_dest,
width, height)) width, height))
return; goto done;
glBegin(GL_QUADS);
for (i = 0; i < REGION_NUM_RECTS(&region); i++) { glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
BoxPtr box = &REGION_RECTS(&region)[i]; glEnableClientState(GL_VERTEX_ARRAY);
glVertex2i(box->x1, box->y1);
glVertex2i(box->x2, box->y1); if (!key.solid_source) {
glVertex2i(box->x2, box->y2); glClientActiveTexture(GL_TEXTURE0);
glVertex2i(box->x1, box->y2); glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, source_texcoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
} }
glEnd();
if (key.has_mask && !key.solid_mask) {
glClientActiveTexture(GL_TEXTURE1);
glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, mask_texcoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
box = REGION_RECTS(&region);
for (i = 0; i < REGION_NUM_RECTS(&region); i++) {
vertices[0][0] = v_from_x_coord_x(dest_pixmap, box[i].x1);
vertices[0][1] = v_from_x_coord_y(dest_pixmap, box[i].y1);
vertices[1][0] = v_from_x_coord_x(dest_pixmap, box[i].x2);
vertices[1][1] = v_from_x_coord_y(dest_pixmap, box[i].y1);
vertices[2][0] = v_from_x_coord_x(dest_pixmap, box[i].x2);
vertices[2][1] = v_from_x_coord_y(dest_pixmap, box[i].y2);
vertices[3][0] = v_from_x_coord_x(dest_pixmap, box[i].x1);
vertices[3][1] = v_from_x_coord_y(dest_pixmap, box[i].y2);
if (!key.solid_source) {
int tx1 = box[i].x1 + x_source - x_dest;
int ty1 = box[i].y1 + y_source - y_dest;
int tx2 = box[i].x2 + x_source - x_dest;
int ty2 = box[i].y2 + y_source - y_dest;
source_texcoords[0][0] = t_from_x_coord_x(source_pixmap, tx1);
source_texcoords[0][1] = t_from_x_coord_y(source_pixmap, ty1);
source_texcoords[1][0] = t_from_x_coord_x(source_pixmap, tx2);
source_texcoords[1][1] = t_from_x_coord_y(source_pixmap, ty1);
source_texcoords[2][0] = t_from_x_coord_x(source_pixmap, tx2);
source_texcoords[2][1] = t_from_x_coord_y(source_pixmap, ty2);
source_texcoords[3][0] = t_from_x_coord_x(source_pixmap, tx1);
source_texcoords[3][1] = t_from_x_coord_y(source_pixmap, ty2);
}
if (key.has_mask && !key.solid_mask) {
int tx1 = box[i].x1 + x_mask - x_dest;
int ty1 = box[i].y1 + y_mask - y_dest;
int tx2 = box[i].x2 + x_mask - x_dest;
int ty2 = box[i].y2 + y_mask - y_dest;
mask_texcoords[0][0] = t_from_x_coord_x(mask_pixmap, tx1);
mask_texcoords[0][1] = t_from_x_coord_y(mask_pixmap, ty1);
mask_texcoords[1][0] = t_from_x_coord_x(mask_pixmap, tx2);
mask_texcoords[1][1] = t_from_x_coord_y(mask_pixmap, ty1);
mask_texcoords[2][0] = t_from_x_coord_x(mask_pixmap, tx2);
mask_texcoords[2][1] = t_from_x_coord_y(mask_pixmap, ty2);
mask_texcoords[3][0] = t_from_x_coord_x(mask_pixmap, tx1);
mask_texcoords[3][1] = t_from_x_coord_y(mask_pixmap, ty2);
}
#if 0
else memset(mask_texcoords, 0, sizeof(mask_texcoords));
for (i = 0; i < 4; i++) {
ErrorF("%d: (%04.4f, %04.4f) (%04.4f, %04.4f) (%04.4f, %04.4f)\n",
i,
source_texcoords[i][0], source_texcoords[i][1],
mask_texcoords[i][0], mask_texcoords[i][1],
vertices[i][0], vertices[i][1]);
}
#endif
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
glClientActiveTexture(GL_TEXTURE0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTexture(GL_TEXTURE1);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
done:
REGION_UNINIT(dst->pDrawable->pScreen, &region);
glDisable(GL_BLEND); glDisable(GL_BLEND);
glActiveTexture(GL_TEXTURE0);
glDisable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE1);
glDisable(GL_TEXTURE_2D);
glUseProgramObjectARB(0); glUseProgramObjectARB(0);
REGION_UNINIT(pDst->pDrawable->pScreen, &region); return TRUE;
return;
fail: fail:
glDisable(GL_BLEND);
glUseProgramObjectARB(0);
return FALSE;
}
void
glamor_composite(CARD8 op,
PicturePtr source,
PicturePtr mask,
PicturePtr dest,
INT16 x_source,
INT16 y_source,
INT16 x_mask,
INT16 y_mask,
INT16 x_dest,
INT16 y_dest,
CARD16 width,
CARD16 height)
{
/* Do two-pass PictOpOver componentAlpha, until we enable
* dual source color blending.
*/
if (mask && mask->componentAlpha)
goto fail;
if (mask && mask->componentAlpha && op == PictOpOver) {
glamor_composite(PictOpOutReverse,
source, mask, dest,
x_source, y_source,
x_mask, y_mask,
x_dest, y_dest,
width, height);
glamor_composite(PictOpAdd,
source, mask, dest,
x_source, y_source,
x_mask, y_mask,
x_dest, y_dest,
width, height);
return;
}
if (!mask) {
if (glamor_composite_with_copy(op, source, dest,
x_source, y_source,
x_dest, y_dest,
width, height))
return;
}
if (glamor_composite_with_shader(op, source, mask, dest,
x_source, y_source,
x_mask, y_mask,
x_dest, y_dest,
width, height))
return;
glamor_fallback("glamor_composite(): " glamor_fallback("glamor_composite(): "
"from picts %p/%p(%c,%c) to pict %p (%c)\n", "from picts %p/%p(%c,%c) to pict %p (%c)\n",
source, mask, source, mask,
@ -678,8 +759,9 @@ fail:
glamor_get_picture_location(mask), glamor_get_picture_location(mask),
dest, dest,
glamor_get_picture_location(dest)); glamor_get_picture_location(dest));
fail:
glUseProgramObjectARB(0); glUseProgramObjectARB(0);
glDisable(GL_BLEND);
if (glamor_prepare_access(dest->pDrawable, GLAMOR_ACCESS_RW)) { if (glamor_prepare_access(dest->pDrawable, GLAMOR_ACCESS_RW)) {
if (source->pDrawable == NULL || if (source->pDrawable == NULL ||
glamor_prepare_access(source->pDrawable, GLAMOR_ACCESS_RO)) glamor_prepare_access(source->pDrawable, GLAMOR_ACCESS_RO))