From: Anthony Waters <[email protected]> The method __glamor_upload_pixmap_to_texture was updated to support a stride parameter for the data being uploaded to a texture. This required correctly setting the alignment from 4 to a value based on the depth of the data and also required setting GL_UNPACK_ROW_LENGTH based on both the stride and the alignment.
The stride parameter was also updated in glamor_put_image to be correctly specified, the old values would cause the xserver to crash. [ Michel Dänzer: squashed in follow-up fix for the stride ] Part of bug: https://bugs.freedesktop.org/show_bug.cgi?id=71813 Signed-off-by: Anthony Waters <[email protected]> Signed-off-by: Alex Deucher <[email protected]> Signed-off-by: Michel Dänzer <[email protected]> --- glamor/glamor_pixmap.c | 38 +++++++++++++++++++++++++++++++++----- glamor/glamor_putimage.c | 6 ++++-- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index 54b414b..8846741 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -697,13 +697,38 @@ static void __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex, GLenum format, GLenum type, - int x, int y, int w, int h, + int x, int y, int w, int h, int stride, void *bits, int pbo) { glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); int non_sub = 0; unsigned int iformat = 0; + int bpp, alignment; + + switch (type) { + case GL_UNSIGNED_BYTE: + bpp = 8; + break; + case GL_UNSIGNED_INT_8_8_8_8: + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_UNSIGNED_INT_2_10_10_10_REV: + bpp = 32; + break; + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_5_6_5_REV: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + bpp = 16; + break; + default: + bpp = 0; + } + alignment = bpp / 8; + + if (stride == 0) { + alignment = 4; + } glamor_make_current(glamor_priv); if (*tex == 0) { @@ -719,17 +744,20 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex, glBindTexture(GL_TEXTURE_2D, *tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); assert(pbo || bits != 0); if (bits == NULL) { glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo); glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); } + + glPixelStorei(GL_UNPACK_ROW_LENGTH, stride / alignment); if (non_sub) glTexImage2D(GL_TEXTURE_2D, 0, iformat, w, h, 0, format, type, bits); else glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, format, type, bits); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); if (bits == NULL) glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); @@ -812,7 +840,7 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, assert(y + fbo_y_off + h <= pixmap_priv->base.fbo->height); __glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->base.fbo->tex, format, type, - x + fbo_x_off, y + fbo_y_off, w, h, + x + fbo_x_off, y + fbo_y_off, w, h, stride, bits, pbo); return TRUE; } @@ -838,8 +866,8 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); glamor_set_destination_pixmap_priv_nc(pixmap_priv); - __glamor_upload_pixmap_to_texture(pixmap, &tex, - format, type, 0, 0, w, h, bits, pbo); + __glamor_upload_pixmap_to_texture(pixmap, &tex, format, type, + 0, 0, w, h, stride, bits, pbo); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tex); diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index cf7197b..79e3e13 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -55,6 +55,7 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, PixmapPtr temp_pixmap, sub_pixmap; glamor_pixmap_private *temp_pixmap_priv; BoxRec box; + int stride; glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off); clip = fbGetCompositeClip(gc); @@ -78,6 +79,7 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, } /* create a temporary pixmap and upload the bits to that * pixmap, then apply clip copy it to the destination pixmap.*/ + stride = PixmapBytePad(w, depth); box.x1 = x + drawable->x; box.y1 = y + drawable->y; box.x2 = x + w + drawable->x; @@ -97,7 +99,7 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, } glamor_upload_sub_pixmap_to_texture(temp_pixmap, 0, 0, w, h, - pixmap->devKind, bits, 0); + stride, bits, 0); glamor_copy_area(&temp_pixmap->drawable, drawable, gc, 0, 0, w, h, x, y); @@ -106,7 +108,7 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, else glamor_upload_sub_pixmap_to_texture(pixmap, x + drawable->x + x_off, y + drawable->y + y_off, w, h, - PixmapBytePad(w, depth), bits, 0); + stride, bits, 0); ret = TRUE; goto done; -- 1.9.2 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
