mirror of
https://github.com/brl/mutter.git
synced 2024-12-03 05:10:40 -05:00
cogl-texture-driver-gles: Don't copy the bitmap if alignment matches
When uploading data for GLES we need to deal with cases where the rowstride is too large to be described only by GL_UNPACK_ALIGNMENT because there is no GL_UNPACK_ROW_LENGTH. Previously for the sub-region uploading code it would always copy the bitmap and for the code to upload the whole image it would copy the bitmap unless the rowstride == bpp*width. Neither paths took into account that we don't need to copy if the rowstride is just an alignment of bpp*width. This moves the bitmap copying code to a separate function that is used by both upload methods. It only copies the bitmap if the rowstride is not just an alignment of bpp*width. http://bugzilla.clutter-project.org/show_bug.cgi?id=2491
This commit is contained in:
parent
14e94647bf
commit
0f43e01cbc
@ -97,6 +97,32 @@ _cogl_texture_driver_prep_gl_for_pixels_download (int pixels_rowstride,
|
|||||||
_cogl_texture_prep_gl_alignment_for_pixels_download (pixels_rowstride);
|
_cogl_texture_prep_gl_alignment_for_pixels_download (pixels_rowstride);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CoglBitmap *
|
||||||
|
prepare_bitmap_alignment_for_upload (CoglBitmap *src_bmp)
|
||||||
|
{
|
||||||
|
CoglPixelFormat format = _cogl_bitmap_get_format (src_bmp);
|
||||||
|
int bpp = _cogl_get_format_bpp (format);
|
||||||
|
int src_rowstride = _cogl_bitmap_get_rowstride (src_bmp);
|
||||||
|
int width = _cogl_bitmap_get_width (src_bmp);
|
||||||
|
int alignment = 1;
|
||||||
|
|
||||||
|
if (src_rowstride == 0)
|
||||||
|
return cogl_object_ref (src_bmp);
|
||||||
|
|
||||||
|
/* Work out the alignment of the source rowstride */
|
||||||
|
alignment = 1 << (_cogl_util_ffs (src_rowstride) - 1);
|
||||||
|
alignment = MIN (alignment, 8);
|
||||||
|
|
||||||
|
/* If the aligned data equals the rowstride then we can upload from
|
||||||
|
the bitmap directly using GL_UNPACK_ALIGNMENT */
|
||||||
|
if (((width * bpp + alignment - 1) & ~(alignment - 1)) == src_rowstride)
|
||||||
|
return cogl_object_ref (src_bmp);
|
||||||
|
/* Otherwise we need to copy the bitmap to pack the alignment
|
||||||
|
because GLES has no GL_ROW_LENGTH */
|
||||||
|
else
|
||||||
|
return _cogl_bitmap_copy (src_bmp);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_cogl_texture_driver_upload_subregion_to_gl (GLenum gl_target,
|
_cogl_texture_driver_upload_subregion_to_gl (GLenum gl_target,
|
||||||
GLuint gl_handle,
|
GLuint gl_handle,
|
||||||
@ -117,37 +143,36 @@ _cogl_texture_driver_upload_subregion_to_gl (GLenum gl_target,
|
|||||||
CoglBitmap *slice_bmp;
|
CoglBitmap *slice_bmp;
|
||||||
int rowstride;
|
int rowstride;
|
||||||
|
|
||||||
/* NB: GLES doesn't support the GL_UNPACK_ROW_LENGTH,
|
/* If we are copying a sub region of the source bitmap then we need
|
||||||
* GL_UNPACK_SKIP_PIXELS or GL_UNPACK_SKIP_ROWS pixel store options
|
to copy it because GLES does not support GL_UNPACK_ROW_LENGTH */
|
||||||
* so we can't directly source a sub-region from source_bmp, we need
|
if (src_x != 0 || src_y != 0 ||
|
||||||
* to use a transient bitmap instead. */
|
width != _cogl_bitmap_get_width (source_bmp) ||
|
||||||
|
height != _cogl_bitmap_get_height (source_bmp))
|
||||||
/* FIXME: optimize by not copying to intermediate slice bitmap when
|
{
|
||||||
* source rowstride = bpp * width and the texture image is not
|
rowstride = bpp * width;
|
||||||
* sliced */
|
rowstride = (rowstride + 3) & ~3;
|
||||||
|
slice_bmp =
|
||||||
/* Setup temp bitmap for slice subregion */
|
_cogl_bitmap_new_from_data (g_malloc (height * rowstride),
|
||||||
rowstride = bpp * width;
|
source_format,
|
||||||
slice_bmp = _cogl_bitmap_new_from_data (g_malloc (rowstride * height),
|
width, height,
|
||||||
source_format,
|
rowstride,
|
||||||
width,
|
(CoglBitmapDestroyNotify) g_free,
|
||||||
height,
|
NULL);
|
||||||
rowstride,
|
_cogl_bitmap_copy_subregion (source_bmp,
|
||||||
(CoglBitmapDestroyNotify)
|
slice_bmp,
|
||||||
g_free,
|
src_x, src_y,
|
||||||
NULL);
|
0, 0, /* dst_x/y */
|
||||||
|
width, height);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
slice_bmp = prepare_bitmap_alignment_for_upload (source_bmp);
|
||||||
|
rowstride = _cogl_bitmap_get_rowstride (slice_bmp);
|
||||||
|
}
|
||||||
|
|
||||||
/* Setup gl alignment to match rowstride and top-left corner */
|
/* Setup gl alignment to match rowstride and top-left corner */
|
||||||
_cogl_texture_driver_prep_gl_for_pixels_upload (rowstride, bpp);
|
_cogl_texture_driver_prep_gl_for_pixels_upload (rowstride, bpp);
|
||||||
|
|
||||||
/* Copy subregion data */
|
|
||||||
_cogl_bitmap_copy_subregion (source_bmp,
|
|
||||||
slice_bmp,
|
|
||||||
src_x,
|
|
||||||
src_y,
|
|
||||||
0, 0,
|
|
||||||
width, height);
|
|
||||||
|
|
||||||
data = _cogl_bitmap_bind (slice_bmp, COGL_BUFFER_ACCESS_READ, 0);
|
data = _cogl_bitmap_bind (slice_bmp, COGL_BUFFER_ACCESS_READ, 0);
|
||||||
|
|
||||||
_cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign);
|
_cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign);
|
||||||
@ -174,32 +199,14 @@ _cogl_texture_driver_upload_to_gl (GLenum gl_target,
|
|||||||
GLuint source_gl_type)
|
GLuint source_gl_type)
|
||||||
{
|
{
|
||||||
int bpp = _cogl_get_format_bpp (_cogl_bitmap_get_format (source_bmp));
|
int bpp = _cogl_get_format_bpp (_cogl_bitmap_get_format (source_bmp));
|
||||||
int rowstride = _cogl_bitmap_get_rowstride (source_bmp);
|
int rowstride;
|
||||||
int bmp_width = _cogl_bitmap_get_width (source_bmp);
|
int bmp_width = _cogl_bitmap_get_width (source_bmp);
|
||||||
int bmp_height = _cogl_bitmap_get_height (source_bmp);
|
int bmp_height = _cogl_bitmap_get_height (source_bmp);
|
||||||
CoglBitmap *bmp;
|
CoglBitmap *bmp;
|
||||||
guint8 *data;
|
guint8 *data;
|
||||||
|
|
||||||
/* If the rowstride can't be specified with just GL_ALIGNMENT alone
|
bmp = prepare_bitmap_alignment_for_upload (source_bmp);
|
||||||
then we need to copy the bitmap because there is no GL_ROW_LENGTH */
|
rowstride = _cogl_bitmap_get_rowstride (bmp);
|
||||||
if (rowstride / bpp != bmp_width)
|
|
||||||
{
|
|
||||||
bmp = _cogl_bitmap_new_from_data (g_malloc (rowstride * bmp_height),
|
|
||||||
_cogl_bitmap_get_format (source_bmp),
|
|
||||||
bmp_width,
|
|
||||||
bmp_height,
|
|
||||||
rowstride,
|
|
||||||
(CoglBitmapDestroyNotify) g_free,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
_cogl_bitmap_copy_subregion (source_bmp,
|
|
||||||
bmp,
|
|
||||||
0, 0, 0, 0,
|
|
||||||
bmp_width,
|
|
||||||
bmp_height);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
bmp = cogl_object_ref (source_bmp);
|
|
||||||
|
|
||||||
/* Setup gl alignment to match rowstride and top-left corner */
|
/* Setup gl alignment to match rowstride and top-left corner */
|
||||||
_cogl_texture_driver_prep_gl_for_pixels_upload (rowstride, bpp);
|
_cogl_texture_driver_prep_gl_for_pixels_upload (rowstride, bpp);
|
||||||
|
Loading…
Reference in New Issue
Block a user