cogl-texture: Share the common code in the set_region virtual

There was a lot of common code that was copied to all of the backends
to convert the data to a suitable format and wrap it into a CoglBitmap
so that it can be passed to _cogl_texture_driver_upload_subregion_to_gl.
This patch moves the common code to cogl-texture.c so that the virtual
just takes a CoglBitmap that is already in the right format.
This commit is contained in:
Neil Roberts 2010-07-08 15:15:22 +01:00
parent 972c0c24f0
commit 8beb49164f
8 changed files with 134 additions and 240 deletions

View File

@ -520,79 +520,32 @@ _cogl_atlas_texture_set_region (CoglTexture *tex,
int dst_y, int dst_y,
unsigned int dst_width, unsigned int dst_width,
unsigned int dst_height, unsigned int dst_height,
int width, CoglBitmap *bmp)
int height,
CoglPixelFormat format,
unsigned int rowstride,
const guint8 *data)
{ {
CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex);
/* If the texture is in the atlas then we need to copy the edge /* If the texture is in the atlas then we need to copy the edge
pixels to the border */ pixels to the border */
if (atlas_tex->in_atlas) if (atlas_tex->in_atlas)
{ /* Upload the data ignoring the premult bit */
int bpp; return _cogl_atlas_texture_set_region_with_border (atlas_tex,
CoglBitmap source_bmp; src_x, src_y,
CoglBitmap tmp_bmp; dst_x, dst_y,
gboolean tmp_bmp_owner = FALSE; dst_width, dst_height,
gboolean success; bmp->width,
bmp->height,
bmp->format &
~COGL_PREMULT_BIT,
bmp->rowstride,
bmp->data);
/* Check for valid format */
if (format == COGL_PIXEL_FORMAT_ANY)
return FALSE;
/* Shortcut out early if the image is empty */
if (width == 0 || height == 0)
return TRUE;
/* Init source bitmap */
source_bmp.width = width;
source_bmp.height = height;
source_bmp.format = format;
source_bmp.data = (guint8 *)data;
/* Rowstride from width if none specified */
bpp = _cogl_get_format_bpp (format);
source_bmp.rowstride = (rowstride == 0) ? width * bpp : rowstride;
/* Prepare the bitmap so that it will do the premultiplication
conversion */
_cogl_texture_prepare_for_upload (&source_bmp,
atlas_tex->format,
NULL,
&tmp_bmp,
&tmp_bmp_owner,
NULL, NULL, NULL);
/* Upload the data ignoring the premult bit */
success =
_cogl_atlas_texture_set_region_with_border (atlas_tex,
src_x, src_y,
dst_x, dst_y,
dst_width, dst_height,
tmp_bmp.width,
tmp_bmp.height,
tmp_bmp.format &
~COGL_PREMULT_BIT,
tmp_bmp.rowstride,
tmp_bmp.data);
/* Free data if owner */
if (tmp_bmp_owner)
g_free (tmp_bmp.data);
return success;
}
else else
/* Otherwise we can just forward on to the sub texture */ /* Otherwise we can just forward on to the sub texture */
return cogl_texture_set_region (atlas_tex->sub_texture, return _cogl_texture_set_region_from_bitmap (atlas_tex->sub_texture,
src_x, src_y, src_x, src_y,
dst_x, dst_y, dst_x, dst_y,
dst_width, dst_height, dst_width, dst_height,
width, height, bmp);
format, rowstride,
data);
} }
static gboolean static gboolean

View File

@ -406,23 +406,16 @@ _cogl_sub_texture_set_region (CoglTexture *tex,
int dst_y, int dst_y,
unsigned int dst_width, unsigned int dst_width,
unsigned int dst_height, unsigned int dst_height,
int width, CoglBitmap *bmp)
int height,
CoglPixelFormat format,
unsigned int rowstride,
const guint8 *data)
{ {
CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex);
return cogl_texture_set_region (sub_tex->full_texture, return _cogl_texture_set_region_from_bitmap (sub_tex->full_texture,
src_x, src_y, src_x, src_y,
dst_x + sub_tex->sub_x, dst_x + sub_tex->sub_x,
dst_y + sub_tex->sub_y, dst_y + sub_tex->sub_y,
dst_width, dst_height, dst_width, dst_height,
width, height, bmp);
format,
rowstride,
data);
} }
static void static void

View File

@ -1461,62 +1461,25 @@ _cogl_texture_2d_sliced_set_region (CoglTexture *tex,
int dst_y, int dst_y,
unsigned int dst_width, unsigned int dst_width,
unsigned int dst_height, unsigned int dst_height,
int width, CoglBitmap *bmp)
int height,
CoglPixelFormat format,
unsigned int rowstride,
const guint8 *data)
{ {
CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex);
int bpp; GLenum gl_format;
CoglBitmap source_bmp; GLenum gl_type;
CoglBitmap tmp_bmp;
gboolean tmp_bmp_owner = FALSE;
GLenum closest_gl_format;
GLenum closest_gl_type;
/* Check for valid format */
if (format == COGL_PIXEL_FORMAT_ANY)
return FALSE;
/* Shortcut out early if the image is empty */
if (width == 0 || height == 0)
return TRUE;
/* Init source bitmap */
source_bmp.width = width;
source_bmp.height = height;
source_bmp.format = format;
source_bmp.data = (guint8 *)data;
/* Rowstride from width if none specified */
bpp = _cogl_get_format_bpp (format);
source_bmp.rowstride = (rowstride == 0) ? width * bpp : rowstride;
/* Prepare the bitmap so that it will do the premultiplication
conversion */
_cogl_texture_prepare_for_upload (&source_bmp,
tex_2ds->format,
NULL,
&tmp_bmp,
&tmp_bmp_owner,
NULL,
&closest_gl_format,
&closest_gl_type);
_cogl_pixel_format_to_gl (bmp->format,
NULL, /* internal format */
&gl_format,
&gl_type);
/* Send data to GL */ /* Send data to GL */
_cogl_texture_2d_sliced_upload_subregion_to_gl (tex_2ds, _cogl_texture_2d_sliced_upload_subregion_to_gl (tex_2ds,
src_x, src_y, src_x, src_y,
dst_x, dst_y, dst_x, dst_y,
dst_width, dst_height, dst_width, dst_height,
&tmp_bmp, bmp,
closest_gl_format, gl_format,
closest_gl_type); gl_type);
/* Free data if owner */
if (tmp_bmp_owner)
g_free (tmp_bmp.data);
return TRUE; return TRUE;
} }

View File

@ -450,48 +450,16 @@ _cogl_texture_2d_set_region (CoglTexture *tex,
int dst_y, int dst_y,
unsigned int dst_width, unsigned int dst_width,
unsigned int dst_height, unsigned int dst_height,
int width, CoglBitmap *bmp)
int height,
CoglPixelFormat format,
unsigned int rowstride,
const guint8 *data)
{ {
CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex);
int bpp; GLenum gl_format;
CoglBitmap source_bmp; GLenum gl_type;
CoglBitmap tmp_bmp;
gboolean tmp_bmp_owner = FALSE;
GLenum closest_gl_format;
GLenum closest_gl_type;
/* Check for valid format */ _cogl_pixel_format_to_gl (bmp->format,
if (format == COGL_PIXEL_FORMAT_ANY) NULL, /* internal format */
return FALSE; &gl_format,
&gl_type);
/* Shortcut out early if the image is empty */
if (width == 0 || height == 0)
return TRUE;
/* Init source bitmap */
source_bmp.width = width;
source_bmp.height = height;
source_bmp.format = format;
source_bmp.data = (guint8 *)data;
/* Rowstride from width if none specified */
bpp = _cogl_get_format_bpp (format);
source_bmp.rowstride = (rowstride == 0) ? width * bpp : rowstride;
/* Prepare the bitmap so that it will do the premultiplication
conversion */
_cogl_texture_prepare_for_upload (&source_bmp,
tex_2d->format,
NULL,
&tmp_bmp,
&tmp_bmp_owner,
NULL,
&closest_gl_format,
&closest_gl_type);
/* Send data to GL */ /* Send data to GL */
_cogl_texture_driver_upload_subregion_to_gl (GL_TEXTURE_2D, _cogl_texture_driver_upload_subregion_to_gl (GL_TEXTURE_2D,
@ -500,13 +468,9 @@ _cogl_texture_2d_set_region (CoglTexture *tex,
src_x, src_y, src_x, src_y,
dst_x, dst_y, dst_x, dst_y,
dst_width, dst_height, dst_width, dst_height,
&tmp_bmp, bmp,
closest_gl_format, gl_format,
closest_gl_type); gl_type);
/* Free data if owner */
if (tmp_bmp_owner)
g_free (tmp_bmp.data);
tex_2d->mipmaps_dirty = TRUE; tex_2d->mipmaps_dirty = TRUE;

View File

@ -68,6 +68,9 @@ struct _CoglTextureVtable
/* Virtual functions that must be implemented for a texture /* Virtual functions that must be implemented for a texture
backend */ backend */
/* This should update the specified sub region of the texture with a
sub region of the given bitmap. The bitmap will have first been
converted to a suitable format for uploading if neccessary. */
gboolean (* set_region) (CoglTexture *tex, gboolean (* set_region) (CoglTexture *tex,
int src_x, int src_x,
int src_y, int src_y,
@ -75,11 +78,7 @@ struct _CoglTextureVtable
int dst_y, int dst_y,
unsigned int dst_width, unsigned int dst_width,
unsigned int dst_height, unsigned int dst_height,
int width, CoglBitmap *bitmap);
int height,
CoglPixelFormat format,
unsigned int rowstride,
const guint8 *data);
/* This should copy the image data of the texture into @data. The /* This should copy the image data of the texture into @data. The
requested format will have been first passed through requested format will have been first passed through
@ -258,4 +257,14 @@ _cogl_texture_draw_and_read (CoglHandle handle,
gboolean gboolean
_cogl_texture_is_foreign (CoglHandle handle); _cogl_texture_is_foreign (CoglHandle handle);
gboolean
_cogl_texture_set_region_from_bitmap (CoglHandle handle,
int src_x,
int src_y,
int dst_x,
int dst_y,
unsigned int dst_width,
unsigned int dst_height,
CoglBitmap *bmp);
#endif /* __COGL_TEXTURE_PRIVATE_H */ #endif /* __COGL_TEXTURE_PRIVATE_H */

View File

@ -446,48 +446,16 @@ _cogl_texture_rectangle_set_region (CoglTexture *tex,
int dst_y, int dst_y,
unsigned int dst_width, unsigned int dst_width,
unsigned int dst_height, unsigned int dst_height,
int width, CoglBitmap *bmp)
int height,
CoglPixelFormat format,
unsigned int rowstride,
const guint8 *data)
{ {
CoglTextureRectangle *tex_rect = COGL_TEXTURE_RECTANGLE (tex); CoglTextureRectangle *tex_rect = COGL_TEXTURE_RECTANGLE (tex);
int bpp; GLenum gl_format;
CoglBitmap source_bmp; GLenum gl_type;
CoglBitmap tmp_bmp;
gboolean tmp_bmp_owner = FALSE;
GLenum closest_gl_format;
GLenum closest_gl_type;
/* Check for valid format */ _cogl_pixel_format_to_gl (bmp->format,
if (format == COGL_PIXEL_FORMAT_ANY) NULL, /* internal format */
return FALSE; &gl_format,
&gl_type);
/* Shortcut out early if the image is empty */
if (width == 0 || height == 0)
return TRUE;
/* Init source bitmap */
source_bmp.width = width;
source_bmp.height = height;
source_bmp.format = format;
source_bmp.data = (guint8 *)data;
/* Rowstride from width if none specified */
bpp = _cogl_get_format_bpp (format);
source_bmp.rowstride = (rowstride == 0) ? width * bpp : rowstride;
/* Prepare the bitmap so that it will do the premultiplication
conversion */
_cogl_texture_prepare_for_upload (&source_bmp,
tex_rect->format,
NULL,
&tmp_bmp,
&tmp_bmp_owner,
NULL,
&closest_gl_format,
&closest_gl_type);
/* Send data to GL */ /* Send data to GL */
_cogl_texture_driver_upload_subregion_to_gl (GL_TEXTURE_RECTANGLE_ARB, _cogl_texture_driver_upload_subregion_to_gl (GL_TEXTURE_RECTANGLE_ARB,
@ -496,13 +464,9 @@ _cogl_texture_rectangle_set_region (CoglTexture *tex,
src_x, src_y, src_x, src_y,
dst_x, dst_y, dst_x, dst_y,
dst_width, dst_height, dst_width, dst_height,
&tmp_bmp, bmp,
closest_gl_format, gl_format,
closest_gl_type); gl_type);
/* Free data if owner */
if (tmp_bmp_owner)
g_free (tmp_bmp.data);
return TRUE; return TRUE;
} }

View File

@ -812,6 +812,51 @@ _cogl_texture_ensure_non_quad_rendering (CoglHandle handle)
tex->vtable->ensure_non_quad_rendering (tex); tex->vtable->ensure_non_quad_rendering (tex);
} }
gboolean
_cogl_texture_set_region_from_bitmap (CoglHandle handle,
int src_x,
int src_y,
int dst_x,
int dst_y,
unsigned int dst_width,
unsigned int dst_height,
CoglBitmap *bmp)
{
CoglTexture *tex = COGL_TEXTURE (handle);
CoglBitmap tmp_bmp;
gboolean tmp_bmp_owner = FALSE;
GLenum closest_gl_format;
GLenum closest_gl_type;
gboolean ret;
/* Shortcut out early if the image is empty */
if (dst_width == 0 || dst_height == 0)
return TRUE;
/* Prepare the bitmap so that it will do the premultiplication
conversion */
_cogl_texture_prepare_for_upload (bmp,
cogl_texture_get_format (handle),
NULL,
&tmp_bmp,
&tmp_bmp_owner,
NULL,
&closest_gl_format,
&closest_gl_type);
ret = tex->vtable->set_region (handle,
src_x, src_y,
dst_x, dst_y,
dst_width, dst_height,
&tmp_bmp);
/* Free data if owner */
if (tmp_bmp_owner)
g_free (tmp_bmp.data);
return ret;
}
gboolean gboolean
cogl_texture_set_region (CoglHandle handle, cogl_texture_set_region (CoglHandle handle,
int src_x, int src_x,
@ -826,21 +871,28 @@ cogl_texture_set_region (CoglHandle handle,
unsigned int rowstride, unsigned int rowstride,
const guint8 *data) const guint8 *data)
{ {
CoglTexture *tex; int bpp;
CoglBitmap source_bmp;
if (!cogl_is_texture (handle)) /* Check for valid format */
if (format == COGL_PIXEL_FORMAT_ANY)
return FALSE; return FALSE;
tex = COGL_TEXTURE (handle); /* Init source bitmap */
source_bmp.width = width;
source_bmp.height = height;
source_bmp.format = format;
source_bmp.data = (guint8 *) data;
return tex->vtable->set_region (tex, /* Rowstride from width if none specified */
src_x, src_y, bpp = _cogl_get_format_bpp (format);
dst_x, dst_y, source_bmp.rowstride = (rowstride == 0) ? width * bpp : rowstride;
dst_width, dst_height,
width, height, return _cogl_texture_set_region_from_bitmap (handle,
format, src_x, src_y,
rowstride, dst_x, dst_y,
data); dst_width, dst_height,
&source_bmp);
} }
/* Reads back the contents of a texture by rendering it to the framebuffer /* Reads back the contents of a texture by rendering it to the framebuffer

View File

@ -1118,11 +1118,7 @@ _cogl_texture_pixmap_x11_set_region (CoglTexture *tex,
int dst_y, int dst_y,
unsigned int dst_width, unsigned int dst_width,
unsigned int dst_height, unsigned int dst_height,
int width, CoglBitmap *bmp)
int height,
CoglPixelFormat format,
unsigned int rowstride,
const guint8 *data)
{ {
/* This doesn't make much sense for texture from pixmap so it's not /* This doesn't make much sense for texture from pixmap so it's not
supported */ supported */