From f17767e4c105d1d172d9496646ec22105e107e31 Mon Sep 17 00:00:00 2001 From: Neil Roberts Date: Mon, 30 Nov 2009 12:15:05 +0000 Subject: [PATCH] cogl: Add _cogl_texture_driver_upload_to_gl This provides a way to upload the entire data for a texture without having to first call glTexImage and then glTexSubImage. This should be faster especially with indirect rendering where it would needlessy send the data for the texture twice. --- cogl/cogl-texture-driver.h | 14 ++++++++ cogl/driver/gl/cogl-texture-driver.c | 26 ++++++++++++++ cogl/driver/gles/cogl-texture-driver.c | 47 ++++++++++++++++++++++++++ 3 files changed, 87 insertions(+) diff --git a/cogl/cogl-texture-driver.h b/cogl/cogl-texture-driver.h index 6626d18ff..6961659d8 100644 --- a/cogl/cogl-texture-driver.h +++ b/cogl/cogl-texture-driver.h @@ -69,6 +69,20 @@ _cogl_texture_driver_upload_subregion_to_gl (GLenum gl_target, GLuint source_gl_format, GLuint source_gl_type); +/* + * Replaces the contents of the GL texture with the entire bitmap. On + * GL this just directly calls glTexImage2D, but under GLES it needs + * to copy the bitmap if the rowstride is not a multiple of a possible + * alignment value because there is no GL_UNPACK_ROW_LENGTH + */ +void +_cogl_texture_driver_upload_to_gl (GLenum gl_target, + GLuint gl_handle, + CoglBitmap *source_bmp, + GLint internal_gl_format, + GLuint source_gl_format, + GLuint source_gl_type); + /* * This sets up the glPixelStore state for an download to a destination with * the same size, and with no offset. diff --git a/cogl/driver/gl/cogl-texture-driver.c b/cogl/driver/gl/cogl-texture-driver.c index 024ce9b8a..144474f23 100644 --- a/cogl/driver/gl/cogl-texture-driver.c +++ b/cogl/driver/gl/cogl-texture-driver.c @@ -134,6 +134,32 @@ _cogl_texture_driver_upload_subregion_to_gl (GLenum gl_target, source_bmp->data) ); } +void +_cogl_texture_driver_upload_to_gl (GLenum gl_target, + GLuint gl_handle, + CoglBitmap *source_bmp, + GLint internal_gl_format, + GLuint source_gl_format, + GLuint source_gl_type) +{ + int bpp = _cogl_get_format_bpp (source_bmp->format); + + /* Setup gl alignment to match rowstride and top-left corner */ + prep_gl_for_pixels_upload_full (source_bmp->rowstride, 0, 0, bpp); + + /* We don't need to use _cogl_texture_driver_bind here because we're + not using the bound texture to render yet */ + GE( glBindTexture (gl_target, gl_handle) ); + + GE( glTexImage2D (gl_target, 0, + internal_gl_format, + source_bmp->width, source_bmp->height, + 0, + source_gl_format, + source_gl_type, + source_bmp->data) ); +} + gboolean _cogl_texture_driver_gl_get_tex_image (GLenum gl_target, GLenum dest_gl_format, diff --git a/cogl/driver/gles/cogl-texture-driver.c b/cogl/driver/gles/cogl-texture-driver.c index 42e5af27d..62324f58c 100644 --- a/cogl/driver/gles/cogl-texture-driver.c +++ b/cogl/driver/gles/cogl-texture-driver.c @@ -128,6 +128,53 @@ _cogl_texture_driver_upload_subregion_to_gl (GLenum gl_target, g_free (slice_bmp.data); } +void +_cogl_texture_driver_upload_to_gl (GLenum gl_target, + GLuint gl_handle, + CoglBitmap *source_bmp, + GLint internal_gl_format, + GLuint source_gl_format, + GLuint source_gl_type) +{ + int bpp = _cogl_get_format_bpp (source_bmp->format); + CoglBitmap bmp = *source_bmp; + gboolean bmp_owner = FALSE; + + /* If the rowstride can't be specified with just GL_ALIGNMENT alone + then we need to copy the bitmap because there is no GL_ROW_LENGTH */ + if (source_bmp->rowstride / bpp != source_bmp->width) + { + bmp.rowstride = bpp * bmp.width; + bmp.data = g_malloc (bmp.rowstride * bmp.height); + bmp_owner = TRUE; + + _cogl_bitmap_copy_subregion (source_bmp, + &bmp, + 0, 0, 0, 0, + bmp.width, + bmp.height); + } + + /* Setup gl alignment to match rowstride and top-left corner */ + _cogl_texture_driver_prep_gl_for_pixels_upload (bmp.rowstride, + bpp); + + /* We don't need to use _cogl_texture_driver_bind here because we're + not using the bound texture to render yet */ + GE( glBindTexture (gl_target, gl_handle) ); + + GE( glTexImage2D (gl_target, 0, + internal_gl_format, + bmp.width, bmp.height, + 0, + source_gl_format, + source_gl_type, + bmp.data) ); + + if (bmp_owner) + g_free (bmp.data); +} + /* NB: GLES doesn't support glGetTexImage2D, so cogl-texture will instead * fallback to a generic render + readpixels approach to downloading * texture data. (See _cogl_texture_draw_and_read() ) */