cogl: Let GL do the format conversion when uploading texture data
Cogl accepts a pixel format for both the data in memory and the internal format to be used for the texture. If they do not match then it would convert them using the CoglBitmap functions before uploading the data. However, GL also lets you specify both formats so it makes more sense to let GL do the conversion. The driver may need the texture in a specific format so it may end up being converted anyway. The cogl_texture_upload_data functions have been removed and replaced with a single function to prepare the bitmap. This will only do the premultiplication conversion because that is the only part that GL can't do directly.
This commit is contained in:
parent
a6f061e41f
commit
e20c98e548
@ -508,11 +508,8 @@ _cogl_atlas_texture_set_region (CoglTexture *tex,
|
|||||||
{
|
{
|
||||||
gint bpp;
|
gint bpp;
|
||||||
CoglBitmap source_bmp;
|
CoglBitmap source_bmp;
|
||||||
CoglBitmap temp_bmp;
|
CoglBitmap tmp_bmp;
|
||||||
gboolean source_bmp_owner = FALSE;
|
gboolean tmp_bmp_owner = FALSE;
|
||||||
CoglPixelFormat closest_format;
|
|
||||||
GLenum closest_gl_format;
|
|
||||||
GLenum closest_gl_type;
|
|
||||||
gboolean success;
|
gboolean success;
|
||||||
|
|
||||||
/* Check for valid format */
|
/* Check for valid format */
|
||||||
@ -533,25 +530,14 @@ _cogl_atlas_texture_set_region (CoglTexture *tex,
|
|||||||
bpp = _cogl_get_format_bpp (format);
|
bpp = _cogl_get_format_bpp (format);
|
||||||
source_bmp.rowstride = (rowstride == 0) ? width * bpp : rowstride;
|
source_bmp.rowstride = (rowstride == 0) ? width * bpp : rowstride;
|
||||||
|
|
||||||
/* Find closest format to internal that's supported by GL */
|
/* Prepare the bitmap so that it will do the premultiplication
|
||||||
closest_format = _cogl_pixel_format_to_gl (atlas_tex->format,
|
conversion */
|
||||||
NULL, /* don't need */
|
_cogl_texture_prepare_for_upload (&source_bmp,
|
||||||
&closest_gl_format,
|
atlas_tex->format,
|
||||||
&closest_gl_type);
|
NULL,
|
||||||
|
&tmp_bmp,
|
||||||
/* If no direct match, convert */
|
&tmp_bmp_owner,
|
||||||
if (closest_format != format)
|
NULL, NULL, NULL);
|
||||||
{
|
|
||||||
/* Convert to required format */
|
|
||||||
success = _cogl_bitmap_convert_format_and_premult (&source_bmp,
|
|
||||||
&temp_bmp,
|
|
||||||
closest_format);
|
|
||||||
|
|
||||||
/* Swap bitmaps if succeeded */
|
|
||||||
if (!success) return FALSE;
|
|
||||||
source_bmp = temp_bmp;
|
|
||||||
source_bmp_owner = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Upload the data ignoring the premult bit */
|
/* Upload the data ignoring the premult bit */
|
||||||
success =
|
success =
|
||||||
@ -559,16 +545,16 @@ _cogl_atlas_texture_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,
|
||||||
source_bmp.width,
|
tmp_bmp.width,
|
||||||
source_bmp.height,
|
tmp_bmp.height,
|
||||||
source_bmp.format &
|
tmp_bmp.format &
|
||||||
~COGL_PREMULT_BIT,
|
~COGL_PREMULT_BIT,
|
||||||
source_bmp.rowstride,
|
tmp_bmp.rowstride,
|
||||||
source_bmp.data);
|
tmp_bmp.data);
|
||||||
|
|
||||||
/* Free data if owner */
|
/* Free data if owner */
|
||||||
if (source_bmp_owner)
|
if (tmp_bmp_owner)
|
||||||
g_free (source_bmp.data);
|
g_free (tmp_bmp.data);
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
@ -929,7 +915,11 @@ _cogl_atlas_texture_new_from_bitmap (CoglHandle bmp_handle,
|
|||||||
{
|
{
|
||||||
CoglAtlasTexture *atlas_tex;
|
CoglAtlasTexture *atlas_tex;
|
||||||
CoglBitmap *bmp = (CoglBitmap *) bmp_handle;
|
CoglBitmap *bmp = (CoglBitmap *) bmp_handle;
|
||||||
CoglTextureUploadData upload_data;
|
CoglBitmap dst_bmp;
|
||||||
|
gboolean dst_bmp_owner;
|
||||||
|
GLenum gl_intformat;
|
||||||
|
GLenum gl_format;
|
||||||
|
GLenum gl_type;
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE);
|
_COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE);
|
||||||
|
|
||||||
@ -956,18 +946,18 @@ _cogl_atlas_texture_new_from_bitmap (CoglHandle bmp_handle,
|
|||||||
if (!cogl_features_available (COGL_FEATURE_TEXTURE_READ_PIXELS))
|
if (!cogl_features_available (COGL_FEATURE_TEXTURE_READ_PIXELS))
|
||||||
return COGL_INVALID_HANDLE;
|
return COGL_INVALID_HANDLE;
|
||||||
|
|
||||||
upload_data.bitmap = *bmp;
|
|
||||||
upload_data.bitmap_owner = FALSE;
|
|
||||||
|
|
||||||
if (!_cogl_texture_upload_data_prepare_format (&upload_data,
|
|
||||||
&internal_format))
|
|
||||||
{
|
|
||||||
_cogl_texture_upload_data_free (&upload_data);
|
|
||||||
return COGL_INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
COGL_NOTE (ATLAS, "Adding texture of size %ix%i", bmp->width, bmp->height);
|
COGL_NOTE (ATLAS, "Adding texture of size %ix%i", bmp->width, bmp->height);
|
||||||
|
|
||||||
|
if (!_cogl_texture_prepare_for_upload (bmp,
|
||||||
|
internal_format,
|
||||||
|
&internal_format,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&gl_intformat,
|
||||||
|
&gl_format,
|
||||||
|
&gl_type))
|
||||||
|
return COGL_INVALID_HANDLE;
|
||||||
|
|
||||||
/* If the texture is in a strange format then we can't use it */
|
/* If the texture is in a strange format then we can't use it */
|
||||||
if (internal_format != COGL_PIXEL_FORMAT_RGB_888 &&
|
if (internal_format != COGL_PIXEL_FORMAT_RGB_888 &&
|
||||||
(internal_format & ~COGL_PREMULT_BIT) != COGL_PIXEL_FORMAT_RGBA_8888)
|
(internal_format & ~COGL_PREMULT_BIT) != COGL_PIXEL_FORMAT_RGBA_8888)
|
||||||
@ -975,7 +965,6 @@ _cogl_atlas_texture_new_from_bitmap (CoglHandle bmp_handle,
|
|||||||
COGL_NOTE (ATLAS, "Texture can not be added because the "
|
COGL_NOTE (ATLAS, "Texture can not be added because the "
|
||||||
"format is unsupported");
|
"format is unsupported");
|
||||||
|
|
||||||
_cogl_texture_upload_data_free (&upload_data);
|
|
||||||
return COGL_INVALID_HANDLE;
|
return COGL_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -984,8 +973,8 @@ _cogl_atlas_texture_new_from_bitmap (CoglHandle bmp_handle,
|
|||||||
atlas_tex = g_new (CoglAtlasTexture, 1);
|
atlas_tex = g_new (CoglAtlasTexture, 1);
|
||||||
/* We need to fill in the texture size now because it is used in the
|
/* We need to fill in the texture size now because it is used in the
|
||||||
reserve_space function below. We add two pixels for the border */
|
reserve_space function below. We add two pixels for the border */
|
||||||
atlas_tex->rectangle.width = upload_data.bitmap.width + 2;
|
atlas_tex->rectangle.width = bmp->width + 2;
|
||||||
atlas_tex->rectangle.height = upload_data.bitmap.height + 2;
|
atlas_tex->rectangle.height = bmp->height + 2;
|
||||||
|
|
||||||
/* Try to make some space in the atlas for the texture */
|
/* Try to make some space in the atlas for the texture */
|
||||||
if (!_cogl_atlas_texture_reserve_space (atlas_tex,
|
if (!_cogl_atlas_texture_reserve_space (atlas_tex,
|
||||||
@ -993,15 +982,20 @@ _cogl_atlas_texture_new_from_bitmap (CoglHandle bmp_handle,
|
|||||||
atlas_tex->rectangle.height))
|
atlas_tex->rectangle.height))
|
||||||
{
|
{
|
||||||
g_free (atlas_tex);
|
g_free (atlas_tex);
|
||||||
_cogl_texture_upload_data_free (&upload_data);
|
|
||||||
return COGL_INVALID_HANDLE;
|
return COGL_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_cogl_texture_upload_data_convert (&upload_data, internal_format))
|
if (!_cogl_texture_prepare_for_upload (bmp,
|
||||||
|
internal_format,
|
||||||
|
&internal_format,
|
||||||
|
&dst_bmp,
|
||||||
|
&dst_bmp_owner,
|
||||||
|
&gl_intformat,
|
||||||
|
&gl_format,
|
||||||
|
&gl_type))
|
||||||
{
|
{
|
||||||
cogl_atlas_remove_rectangle (ctx->atlas, &atlas_tex->rectangle);
|
cogl_atlas_remove_rectangle (ctx->atlas, &atlas_tex->rectangle);
|
||||||
g_free (atlas_tex);
|
g_free (atlas_tex);
|
||||||
_cogl_texture_upload_data_free (&upload_data);
|
|
||||||
return COGL_INVALID_HANDLE;
|
return COGL_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1019,14 +1013,17 @@ _cogl_atlas_texture_new_from_bitmap (CoglHandle bmp_handle,
|
|||||||
_cogl_atlas_texture_set_region_with_border (atlas_tex,
|
_cogl_atlas_texture_set_region_with_border (atlas_tex,
|
||||||
0, 0,
|
0, 0,
|
||||||
0, 0,
|
0, 0,
|
||||||
upload_data.bitmap.width,
|
dst_bmp.width,
|
||||||
upload_data.bitmap.height,
|
dst_bmp.height,
|
||||||
upload_data.bitmap.width,
|
dst_bmp.width,
|
||||||
upload_data.bitmap.height,
|
dst_bmp.height,
|
||||||
upload_data.bitmap.format &
|
dst_bmp.format &
|
||||||
~COGL_PREMULT_BIT,
|
~COGL_PREMULT_BIT,
|
||||||
upload_data.bitmap.rowstride,
|
dst_bmp.rowstride,
|
||||||
upload_data.bitmap.data);
|
dst_bmp.data);
|
||||||
|
|
||||||
|
if (dst_bmp_owner)
|
||||||
|
g_free (dst_bmp.data);
|
||||||
|
|
||||||
return _cogl_atlas_texture_handle_new (atlas_tex);
|
return _cogl_atlas_texture_handle_new (atlas_tex);
|
||||||
}
|
}
|
||||||
|
@ -213,7 +213,10 @@ _cogl_texture_2d_sliced_allocate_waste_buffer (CoglTexture2DSliced *tex_2ds,
|
|||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_cogl_texture_2d_sliced_upload_to_gl (CoglTexture2DSliced *tex_2ds,
|
_cogl_texture_2d_sliced_upload_to_gl (CoglTexture2DSliced *tex_2ds,
|
||||||
CoglTextureUploadData *upload_data)
|
CoglBitmap *bmp,
|
||||||
|
GLenum gl_intformat,
|
||||||
|
GLenum gl_format,
|
||||||
|
GLenum gl_type)
|
||||||
{
|
{
|
||||||
CoglSpan *x_span;
|
CoglSpan *x_span;
|
||||||
CoglSpan *y_span;
|
CoglSpan *y_span;
|
||||||
@ -222,11 +225,10 @@ _cogl_texture_2d_sliced_upload_to_gl (CoglTexture2DSliced *tex_2ds,
|
|||||||
gint x,y;
|
gint x,y;
|
||||||
guchar *waste_buf;
|
guchar *waste_buf;
|
||||||
|
|
||||||
bpp = _cogl_get_format_bpp (upload_data->bitmap.format);
|
bpp = _cogl_get_format_bpp (bmp->format);
|
||||||
|
|
||||||
waste_buf =
|
waste_buf = _cogl_texture_2d_sliced_allocate_waste_buffer (tex_2ds,
|
||||||
_cogl_texture_2d_sliced_allocate_waste_buffer (tex_2ds,
|
bmp->format);
|
||||||
upload_data->bitmap.format);
|
|
||||||
|
|
||||||
/* Iterate vertical slices */
|
/* Iterate vertical slices */
|
||||||
for (y = 0; y < tex_2ds->slice_y_spans->len; ++y)
|
for (y = 0; y < tex_2ds->slice_y_spans->len; ++y)
|
||||||
@ -252,27 +254,26 @@ _cogl_texture_2d_sliced_upload_to_gl (CoglTexture2DSliced *tex_2ds,
|
|||||||
0, /* dst y */
|
0, /* dst y */
|
||||||
x_span->size - x_span->waste, /* width */
|
x_span->size - x_span->waste, /* width */
|
||||||
y_span->size - y_span->waste, /* height */
|
y_span->size - y_span->waste, /* height */
|
||||||
&upload_data->bitmap,
|
bmp,
|
||||||
upload_data->gl_format,
|
gl_format,
|
||||||
upload_data->gl_type);
|
gl_type);
|
||||||
|
|
||||||
/* Keep a copy of the first pixel if needed */
|
/* Keep a copy of the first pixel if needed */
|
||||||
if (tex_2ds->first_pixels)
|
if (tex_2ds->first_pixels)
|
||||||
{
|
{
|
||||||
memcpy (tex_2ds->first_pixels[slice_num].data,
|
memcpy (tex_2ds->first_pixels[slice_num].data,
|
||||||
upload_data->bitmap.data + x_span->start * bpp
|
bmp->data + x_span->start * bpp
|
||||||
+ y_span->start * upload_data->bitmap.rowstride,
|
+ y_span->start * bmp->rowstride,
|
||||||
bpp);
|
bpp);
|
||||||
tex_2ds->first_pixels[slice_num].gl_format =
|
tex_2ds->first_pixels[slice_num].gl_format = gl_format;
|
||||||
upload_data->gl_format;
|
tex_2ds->first_pixels[slice_num].gl_type = gl_type;
|
||||||
tex_2ds->first_pixels[slice_num].gl_type = upload_data->gl_type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill the waste with a copies of the rightmost pixels */
|
/* Fill the waste with a copies of the rightmost pixels */
|
||||||
if (x_span->waste > 0)
|
if (x_span->waste > 0)
|
||||||
{
|
{
|
||||||
const guchar *src = upload_data->bitmap.data
|
const guchar *src = bmp->data
|
||||||
+ y_span->start * upload_data->bitmap.rowstride
|
+ y_span->start * bmp->rowstride
|
||||||
+ (x_span->start + x_span->size - x_span->waste - 1) * bpp;
|
+ (x_span->start + x_span->size - x_span->waste - 1) * bpp;
|
||||||
guchar *dst = waste_buf;
|
guchar *dst = waste_buf;
|
||||||
guint wx, wy;
|
guint wx, wy;
|
||||||
@ -284,7 +285,7 @@ _cogl_texture_2d_sliced_upload_to_gl (CoglTexture2DSliced *tex_2ds,
|
|||||||
memcpy (dst, src, bpp);
|
memcpy (dst, src, bpp);
|
||||||
dst += bpp;
|
dst += bpp;
|
||||||
}
|
}
|
||||||
src += upload_data->bitmap.rowstride;
|
src += bmp->rowstride;
|
||||||
}
|
}
|
||||||
|
|
||||||
_cogl_texture_driver_prep_gl_for_pixels_upload (
|
_cogl_texture_driver_prep_gl_for_pixels_upload (
|
||||||
@ -296,15 +297,15 @@ _cogl_texture_2d_sliced_upload_to_gl (CoglTexture2DSliced *tex_2ds,
|
|||||||
0,
|
0,
|
||||||
x_span->waste,
|
x_span->waste,
|
||||||
y_span->size - y_span->waste,
|
y_span->size - y_span->waste,
|
||||||
upload_data->gl_format, upload_data->gl_type,
|
gl_format, gl_type,
|
||||||
waste_buf) );
|
waste_buf) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y_span->waste > 0)
|
if (y_span->waste > 0)
|
||||||
{
|
{
|
||||||
const guchar *src = upload_data->bitmap.data
|
const guchar *src = bmp->data
|
||||||
+ ((y_span->start + y_span->size - y_span->waste - 1)
|
+ ((y_span->start + y_span->size - y_span->waste - 1)
|
||||||
* upload_data->bitmap.rowstride)
|
* bmp->rowstride)
|
||||||
+ x_span->start * bpp;
|
+ x_span->start * bpp;
|
||||||
guchar *dst = waste_buf;
|
guchar *dst = waste_buf;
|
||||||
guint wy, wx;
|
guint wy, wx;
|
||||||
@ -330,7 +331,7 @@ _cogl_texture_2d_sliced_upload_to_gl (CoglTexture2DSliced *tex_2ds,
|
|||||||
y_span->size - y_span->waste,
|
y_span->size - y_span->waste,
|
||||||
x_span->size,
|
x_span->size,
|
||||||
y_span->waste,
|
y_span->waste,
|
||||||
upload_data->gl_format, upload_data->gl_type,
|
gl_format, gl_type,
|
||||||
waste_buf) );
|
waste_buf) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -685,7 +686,10 @@ _cogl_texture_2d_sliced_set_wrap_mode_parameter (CoglTexture *tex,
|
|||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_cogl_texture_2d_sliced_slices_create (CoglTexture2DSliced *tex_2ds,
|
_cogl_texture_2d_sliced_slices_create (CoglTexture2DSliced *tex_2ds,
|
||||||
const CoglTextureUploadData *upload_data)
|
gint width, gint height,
|
||||||
|
GLenum gl_intformat,
|
||||||
|
GLenum gl_format,
|
||||||
|
GLenum gl_type)
|
||||||
{
|
{
|
||||||
gint max_width;
|
gint max_width;
|
||||||
gint max_height;
|
gint max_height;
|
||||||
@ -703,15 +707,15 @@ _cogl_texture_2d_sliced_slices_create (CoglTexture2DSliced *tex_2ds,
|
|||||||
/* Initialize size of largest slice according to supported features */
|
/* Initialize size of largest slice according to supported features */
|
||||||
if (cogl_features_available (COGL_FEATURE_TEXTURE_NPOT))
|
if (cogl_features_available (COGL_FEATURE_TEXTURE_NPOT))
|
||||||
{
|
{
|
||||||
max_width = upload_data->bitmap.width;
|
max_width = width;
|
||||||
max_height = upload_data->bitmap.height;
|
max_height = height;
|
||||||
tex_2ds->gl_target = GL_TEXTURE_2D;
|
tex_2ds->gl_target = GL_TEXTURE_2D;
|
||||||
slices_for_size = _cogl_rect_slices_for_size;
|
slices_for_size = _cogl_rect_slices_for_size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
max_width = cogl_util_next_p2 (upload_data->bitmap.width);
|
max_width = cogl_util_next_p2 (width);
|
||||||
max_height = cogl_util_next_p2 (upload_data->bitmap.height);
|
max_height = cogl_util_next_p2 (height);
|
||||||
tex_2ds->gl_target = GL_TEXTURE_2D;
|
tex_2ds->gl_target = GL_TEXTURE_2D;
|
||||||
slices_for_size = _cogl_pot_slices_for_size;
|
slices_for_size = _cogl_pot_slices_for_size;
|
||||||
}
|
}
|
||||||
@ -723,8 +727,8 @@ _cogl_texture_2d_sliced_slices_create (CoglTexture2DSliced *tex_2ds,
|
|||||||
|
|
||||||
/* Check if size supported else bail out */
|
/* Check if size supported else bail out */
|
||||||
if (!_cogl_texture_driver_size_supported (tex_2ds->gl_target,
|
if (!_cogl_texture_driver_size_supported (tex_2ds->gl_target,
|
||||||
upload_data->gl_intformat,
|
gl_intformat,
|
||||||
upload_data->gl_type,
|
gl_type,
|
||||||
max_width,
|
max_width,
|
||||||
max_height))
|
max_height))
|
||||||
{
|
{
|
||||||
@ -746,19 +750,19 @@ _cogl_texture_2d_sliced_slices_create (CoglTexture2DSliced *tex_2ds,
|
|||||||
/* Add a single span for width and height */
|
/* Add a single span for width and height */
|
||||||
span.start = 0;
|
span.start = 0;
|
||||||
span.size = max_width;
|
span.size = max_width;
|
||||||
span.waste = max_width - upload_data->bitmap.width;
|
span.waste = max_width - width;
|
||||||
g_array_append_val (tex_2ds->slice_x_spans, span);
|
g_array_append_val (tex_2ds->slice_x_spans, span);
|
||||||
|
|
||||||
span.size = max_height;
|
span.size = max_height;
|
||||||
span.waste = max_height - upload_data->bitmap.height;
|
span.waste = max_height - height;
|
||||||
g_array_append_val (tex_2ds->slice_y_spans, span);
|
g_array_append_val (tex_2ds->slice_y_spans, span);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Decrease the size of largest slice until supported by GL */
|
/* Decrease the size of largest slice until supported by GL */
|
||||||
while (!_cogl_texture_driver_size_supported (tex_2ds->gl_target,
|
while (!_cogl_texture_driver_size_supported (tex_2ds->gl_target,
|
||||||
upload_data->gl_intformat,
|
gl_intformat,
|
||||||
upload_data->gl_type,
|
gl_type,
|
||||||
max_width,
|
max_width,
|
||||||
max_height))
|
max_height))
|
||||||
{
|
{
|
||||||
@ -773,11 +777,11 @@ _cogl_texture_2d_sliced_slices_create (CoglTexture2DSliced *tex_2ds,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Determine the slices required to cover the bitmap area */
|
/* Determine the slices required to cover the bitmap area */
|
||||||
n_x_slices = slices_for_size (upload_data->bitmap.width,
|
n_x_slices = slices_for_size (width,
|
||||||
max_width, tex_2ds->max_waste,
|
max_width, tex_2ds->max_waste,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
n_y_slices = slices_for_size (upload_data->bitmap.height,
|
n_y_slices = slices_for_size (height,
|
||||||
max_height, tex_2ds->max_waste,
|
max_height, tex_2ds->max_waste,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
@ -791,11 +795,11 @@ _cogl_texture_2d_sliced_slices_create (CoglTexture2DSliced *tex_2ds,
|
|||||||
n_y_slices);
|
n_y_slices);
|
||||||
|
|
||||||
/* Fill span arrays with info */
|
/* Fill span arrays with info */
|
||||||
slices_for_size (upload_data->bitmap.width,
|
slices_for_size (width,
|
||||||
max_width, tex_2ds->max_waste,
|
max_width, tex_2ds->max_waste,
|
||||||
tex_2ds->slice_x_spans);
|
tex_2ds->slice_x_spans);
|
||||||
|
|
||||||
slices_for_size (upload_data->bitmap.height,
|
slices_for_size (height,
|
||||||
max_height, tex_2ds->max_waste,
|
max_height, tex_2ds->max_waste,
|
||||||
tex_2ds->slice_y_spans);
|
tex_2ds->slice_y_spans);
|
||||||
}
|
}
|
||||||
@ -845,15 +849,15 @@ _cogl_texture_2d_sliced_slices_create (CoglTexture2DSliced *tex_2ds,
|
|||||||
/* Setup texture parameters */
|
/* Setup texture parameters */
|
||||||
GE( _cogl_texture_driver_bind (tex_2ds->gl_target,
|
GE( _cogl_texture_driver_bind (tex_2ds->gl_target,
|
||||||
gl_handles[y * n_x_slices + x],
|
gl_handles[y * n_x_slices + x],
|
||||||
upload_data->gl_intformat) );
|
gl_intformat) );
|
||||||
|
|
||||||
_cogl_texture_driver_try_setting_gl_border_color (tex_2ds->gl_target,
|
_cogl_texture_driver_try_setting_gl_border_color (tex_2ds->gl_target,
|
||||||
transparent_color);
|
transparent_color);
|
||||||
|
|
||||||
/* Pass NULL data to init size and internal format */
|
/* Pass NULL data to init size and internal format */
|
||||||
GE( glTexImage2D (tex_2ds->gl_target, 0, upload_data->gl_intformat,
|
GE( glTexImage2D (tex_2ds->gl_target, 0, gl_intformat,
|
||||||
x_span->size, y_span->size, 0,
|
x_span->size, y_span->size, 0,
|
||||||
upload_data->gl_format, upload_data->gl_type, 0) );
|
gl_format, gl_type, 0) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -894,10 +898,13 @@ _cogl_texture_2d_sliced_free (CoglTexture2DSliced *tex_2ds)
|
|||||||
static gboolean
|
static gboolean
|
||||||
_cogl_texture_2d_sliced_upload_from_data
|
_cogl_texture_2d_sliced_upload_from_data
|
||||||
(CoglTexture2DSliced *tex_2ds,
|
(CoglTexture2DSliced *tex_2ds,
|
||||||
CoglTextureUploadData *upload_data,
|
CoglBitmap *bmp,
|
||||||
CoglPixelFormat internal_format)
|
CoglPixelFormat internal_format)
|
||||||
{
|
{
|
||||||
CoglTexture *tex = COGL_TEXTURE (tex_2ds);
|
CoglTexture *tex = COGL_TEXTURE (tex_2ds);
|
||||||
|
GLenum gl_intformat;
|
||||||
|
GLenum gl_format;
|
||||||
|
GLenum gl_type;
|
||||||
|
|
||||||
tex->vtable = &cogl_texture_2d_sliced_vtable;
|
tex->vtable = &cogl_texture_2d_sliced_vtable;
|
||||||
|
|
||||||
@ -914,36 +921,72 @@ _cogl_texture_2d_sliced_upload_from_data
|
|||||||
tex_2ds->min_filter = GL_FALSE;
|
tex_2ds->min_filter = GL_FALSE;
|
||||||
tex_2ds->mag_filter = GL_FALSE;
|
tex_2ds->mag_filter = GL_FALSE;
|
||||||
|
|
||||||
if (upload_data->bitmap.data)
|
if (bmp->data)
|
||||||
{
|
{
|
||||||
if (!_cogl_texture_upload_data_prepare (upload_data, internal_format))
|
CoglBitmap dst_bmp;
|
||||||
|
gboolean dst_bmp_owner;
|
||||||
|
|
||||||
|
if (!_cogl_texture_prepare_for_upload (bmp,
|
||||||
|
internal_format,
|
||||||
|
&internal_format,
|
||||||
|
&dst_bmp,
|
||||||
|
&dst_bmp_owner,
|
||||||
|
&gl_intformat,
|
||||||
|
&gl_format,
|
||||||
|
&gl_type))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* Create slices for the given format and size */
|
/* Create slices for the given format and size */
|
||||||
if (!_cogl_texture_2d_sliced_slices_create (tex_2ds, upload_data))
|
if (!_cogl_texture_2d_sliced_slices_create (tex_2ds,
|
||||||
return FALSE;
|
bmp->width,
|
||||||
|
bmp->height,
|
||||||
|
gl_intformat,
|
||||||
|
gl_format,
|
||||||
|
gl_type))
|
||||||
|
{
|
||||||
|
if (dst_bmp_owner)
|
||||||
|
g_free (dst_bmp.data);
|
||||||
|
|
||||||
if (!_cogl_texture_2d_sliced_upload_to_gl (tex_2ds, upload_data))
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_cogl_texture_2d_sliced_upload_to_gl (tex_2ds,
|
||||||
|
bmp,
|
||||||
|
gl_intformat,
|
||||||
|
gl_format,
|
||||||
|
gl_type))
|
||||||
|
{
|
||||||
|
if (dst_bmp_owner)
|
||||||
|
g_free (dst_bmp.data);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dst_bmp_owner)
|
||||||
|
g_free (dst_bmp.data);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Find closest GL format match */
|
/* Find closest GL format match */
|
||||||
upload_data->bitmap.format =
|
|
||||||
_cogl_pixel_format_to_gl (internal_format,
|
_cogl_pixel_format_to_gl (internal_format,
|
||||||
&upload_data->gl_intformat,
|
&gl_intformat,
|
||||||
&upload_data->gl_format,
|
&gl_format,
|
||||||
&upload_data->gl_type);
|
&gl_type);
|
||||||
|
|
||||||
/* Create slices for the given format and size */
|
/* Create slices for the given format and size */
|
||||||
if (!_cogl_texture_2d_sliced_slices_create (tex_2ds, upload_data))
|
if (!_cogl_texture_2d_sliced_slices_create (tex_2ds,
|
||||||
|
bmp->width,
|
||||||
|
bmp->height,
|
||||||
|
gl_intformat,
|
||||||
|
gl_format,
|
||||||
|
gl_type))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
tex_2ds->gl_format = upload_data->gl_intformat;
|
tex_2ds->gl_format = gl_intformat;
|
||||||
tex_2ds->width = upload_data->bitmap.width;
|
tex_2ds->width = bmp->width;
|
||||||
tex_2ds->height = upload_data->bitmap.height;
|
tex_2ds->height = bmp->height;
|
||||||
tex_2ds->format = upload_data->bitmap.format;
|
tex_2ds->format = bmp->format;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -956,7 +999,7 @@ _cogl_texture_2d_sliced_new_with_size (unsigned int width,
|
|||||||
{
|
{
|
||||||
CoglTexture2DSliced *tex_2ds;
|
CoglTexture2DSliced *tex_2ds;
|
||||||
CoglTexture *tex;
|
CoglTexture *tex;
|
||||||
CoglTextureUploadData upload_data;
|
CoglBitmap bmp;
|
||||||
|
|
||||||
/* Since no data, we need some internal format */
|
/* Since no data, we need some internal format */
|
||||||
if (internal_format == COGL_PIXEL_FORMAT_ANY)
|
if (internal_format == COGL_PIXEL_FORMAT_ANY)
|
||||||
@ -967,28 +1010,24 @@ _cogl_texture_2d_sliced_new_with_size (unsigned int width,
|
|||||||
|
|
||||||
tex = COGL_TEXTURE (tex_2ds);
|
tex = COGL_TEXTURE (tex_2ds);
|
||||||
|
|
||||||
upload_data.bitmap.width = width;
|
bmp.width = width;
|
||||||
upload_data.bitmap.height = height;
|
bmp.height = height;
|
||||||
upload_data.bitmap.data = NULL;
|
bmp.data = NULL;
|
||||||
upload_data.bitmap_owner = FALSE;
|
|
||||||
|
|
||||||
if ((flags & COGL_TEXTURE_NO_SLICING))
|
if ((flags & COGL_TEXTURE_NO_SLICING))
|
||||||
tex_2ds->max_waste = -1;
|
tex_2ds->max_waste = -1;
|
||||||
else
|
else
|
||||||
tex_2ds->max_waste = COGL_TEXTURE_MAX_WASTE;
|
tex_2ds->max_waste = COGL_TEXTURE_MAX_WASTE;
|
||||||
|
|
||||||
if (!_cogl_texture_2d_sliced_upload_from_data (tex_2ds, &upload_data,
|
if (!_cogl_texture_2d_sliced_upload_from_data (tex_2ds, &bmp,
|
||||||
internal_format))
|
internal_format))
|
||||||
{
|
{
|
||||||
_cogl_texture_2d_sliced_free (tex_2ds);
|
_cogl_texture_2d_sliced_free (tex_2ds);
|
||||||
_cogl_texture_upload_data_free (&upload_data);
|
|
||||||
return COGL_INVALID_HANDLE;
|
return COGL_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
tex_2ds->auto_mipmap = (flags & COGL_TEXTURE_NO_AUTO_MIPMAP) == 0;
|
tex_2ds->auto_mipmap = (flags & COGL_TEXTURE_NO_AUTO_MIPMAP) == 0;
|
||||||
|
|
||||||
_cogl_texture_upload_data_free (&upload_data);
|
|
||||||
|
|
||||||
return _cogl_texture_2d_sliced_handle_new (tex_2ds);
|
return _cogl_texture_2d_sliced_handle_new (tex_2ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1000,7 +1039,6 @@ _cogl_texture_2d_sliced_new_from_bitmap (CoglHandle bmp_handle,
|
|||||||
CoglTexture2DSliced *tex_2ds;
|
CoglTexture2DSliced *tex_2ds;
|
||||||
CoglTexture *tex;
|
CoglTexture *tex;
|
||||||
CoglBitmap *bmp = (CoglBitmap *)bmp_handle;
|
CoglBitmap *bmp = (CoglBitmap *)bmp_handle;
|
||||||
CoglTextureUploadData upload_data;
|
|
||||||
|
|
||||||
g_return_val_if_fail (bmp_handle != COGL_INVALID_HANDLE, COGL_INVALID_HANDLE);
|
g_return_val_if_fail (bmp_handle != COGL_INVALID_HANDLE, COGL_INVALID_HANDLE);
|
||||||
|
|
||||||
@ -1009,9 +1047,6 @@ _cogl_texture_2d_sliced_new_from_bitmap (CoglHandle bmp_handle,
|
|||||||
|
|
||||||
tex = COGL_TEXTURE (tex_2ds);
|
tex = COGL_TEXTURE (tex_2ds);
|
||||||
|
|
||||||
upload_data.bitmap = *bmp;
|
|
||||||
upload_data.bitmap_owner = FALSE;
|
|
||||||
|
|
||||||
if (flags & COGL_TEXTURE_NO_SLICING)
|
if (flags & COGL_TEXTURE_NO_SLICING)
|
||||||
tex_2ds->max_waste = -1;
|
tex_2ds->max_waste = -1;
|
||||||
else
|
else
|
||||||
@ -1025,18 +1060,15 @@ _cogl_texture_2d_sliced_new_from_bitmap (CoglHandle bmp_handle,
|
|||||||
* CoglHandle is returned, it should also be destroyed
|
* CoglHandle is returned, it should also be destroyed
|
||||||
* with cogl_handle_unref at some point! */
|
* with cogl_handle_unref at some point! */
|
||||||
|
|
||||||
if (!_cogl_texture_2d_sliced_upload_from_data (tex_2ds, &upload_data,
|
if (!_cogl_texture_2d_sliced_upload_from_data (tex_2ds, bmp,
|
||||||
internal_format))
|
internal_format))
|
||||||
{
|
{
|
||||||
_cogl_texture_2d_sliced_free (tex_2ds);
|
_cogl_texture_2d_sliced_free (tex_2ds);
|
||||||
_cogl_texture_upload_data_free (&upload_data);
|
|
||||||
return COGL_INVALID_HANDLE;
|
return COGL_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
tex_2ds->auto_mipmap = (flags & COGL_TEXTURE_NO_AUTO_MIPMAP) == 0;
|
tex_2ds->auto_mipmap = (flags & COGL_TEXTURE_NO_AUTO_MIPMAP) == 0;
|
||||||
|
|
||||||
_cogl_texture_upload_data_free (&upload_data);
|
|
||||||
|
|
||||||
return _cogl_texture_2d_sliced_handle_new (tex_2ds);
|
return _cogl_texture_2d_sliced_handle_new (tex_2ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1398,12 +1430,10 @@ _cogl_texture_2d_sliced_set_region (CoglTexture *tex,
|
|||||||
CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex);
|
CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex);
|
||||||
gint bpp;
|
gint bpp;
|
||||||
CoglBitmap source_bmp;
|
CoglBitmap source_bmp;
|
||||||
CoglBitmap temp_bmp;
|
CoglBitmap tmp_bmp;
|
||||||
gboolean source_bmp_owner = FALSE;
|
gboolean tmp_bmp_owner = FALSE;
|
||||||
CoglPixelFormat closest_format;
|
|
||||||
GLenum closest_gl_format;
|
GLenum closest_gl_format;
|
||||||
GLenum closest_gl_type;
|
GLenum closest_gl_type;
|
||||||
gboolean success;
|
|
||||||
|
|
||||||
/* Check for valid format */
|
/* Check for valid format */
|
||||||
if (format == COGL_PIXEL_FORMAT_ANY)
|
if (format == COGL_PIXEL_FORMAT_ANY)
|
||||||
@ -1423,38 +1453,30 @@ _cogl_texture_2d_sliced_set_region (CoglTexture *tex,
|
|||||||
bpp = _cogl_get_format_bpp (format);
|
bpp = _cogl_get_format_bpp (format);
|
||||||
source_bmp.rowstride = (rowstride == 0) ? width * bpp : rowstride;
|
source_bmp.rowstride = (rowstride == 0) ? width * bpp : rowstride;
|
||||||
|
|
||||||
/* Find closest format to internal that's supported by GL */
|
/* Prepare the bitmap so that it will do the premultiplication
|
||||||
closest_format = _cogl_pixel_format_to_gl (tex_2ds->format,
|
conversion */
|
||||||
NULL, /* don't need */
|
_cogl_texture_prepare_for_upload (&source_bmp,
|
||||||
|
tex_2ds->format,
|
||||||
|
NULL,
|
||||||
|
&tmp_bmp,
|
||||||
|
&tmp_bmp_owner,
|
||||||
|
NULL,
|
||||||
&closest_gl_format,
|
&closest_gl_format,
|
||||||
&closest_gl_type);
|
&closest_gl_type);
|
||||||
|
|
||||||
/* If no direct match, convert */
|
|
||||||
if (closest_format != format)
|
|
||||||
{
|
|
||||||
/* Convert to required format */
|
|
||||||
success = _cogl_bitmap_convert_format_and_premult (&source_bmp,
|
|
||||||
&temp_bmp,
|
|
||||||
closest_format);
|
|
||||||
|
|
||||||
/* Swap bitmaps if succeeded */
|
|
||||||
if (!success) return FALSE;
|
|
||||||
source_bmp = temp_bmp;
|
|
||||||
source_bmp_owner = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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,
|
||||||
&source_bmp,
|
&tmp_bmp,
|
||||||
closest_gl_format,
|
closest_gl_format,
|
||||||
closest_gl_type);
|
closest_gl_type);
|
||||||
|
|
||||||
/* Free data if owner */
|
/* Free data if owner */
|
||||||
if (source_bmp_owner)
|
if (tmp_bmp_owner)
|
||||||
g_free (source_bmp.data);
|
g_free (tmp_bmp.data);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -277,40 +277,41 @@ _cogl_texture_2d_new_from_bitmap (CoglHandle bmp_handle,
|
|||||||
{
|
{
|
||||||
CoglTexture2D *tex_2d;
|
CoglTexture2D *tex_2d;
|
||||||
CoglBitmap *bmp = (CoglBitmap *)bmp_handle;
|
CoglBitmap *bmp = (CoglBitmap *)bmp_handle;
|
||||||
CoglTextureUploadData upload_data;
|
CoglBitmap dst_bmp;
|
||||||
|
gboolean dst_bmp_owner;
|
||||||
|
GLenum gl_intformat;
|
||||||
|
GLenum gl_format;
|
||||||
|
GLenum gl_type;
|
||||||
|
|
||||||
g_return_val_if_fail (bmp_handle != COGL_INVALID_HANDLE, COGL_INVALID_HANDLE);
|
g_return_val_if_fail (bmp_handle != COGL_INVALID_HANDLE, COGL_INVALID_HANDLE);
|
||||||
|
|
||||||
upload_data.bitmap = *bmp;
|
if (!_cogl_texture_prepare_for_upload (bmp,
|
||||||
upload_data.bitmap_owner = FALSE;
|
internal_format,
|
||||||
|
&internal_format,
|
||||||
if (!_cogl_texture_upload_data_prepare_format (&upload_data,
|
&dst_bmp,
|
||||||
&internal_format) ||
|
&dst_bmp_owner,
|
||||||
!_cogl_texture_2d_can_create (upload_data.bitmap.width,
|
&gl_intformat,
|
||||||
upload_data.bitmap.height,
|
&gl_format,
|
||||||
internal_format) ||
|
&gl_type))
|
||||||
!_cogl_texture_upload_data_convert (&upload_data, internal_format))
|
|
||||||
{
|
|
||||||
_cogl_texture_upload_data_free (&upload_data);
|
|
||||||
return COGL_INVALID_HANDLE;
|
return COGL_INVALID_HANDLE;
|
||||||
}
|
|
||||||
|
|
||||||
tex_2d = _cogl_texture_2d_create_base (upload_data.bitmap.width,
|
tex_2d = _cogl_texture_2d_create_base (bmp->width,
|
||||||
upload_data.bitmap.height,
|
bmp->height,
|
||||||
flags,
|
flags,
|
||||||
upload_data.bitmap.format);
|
internal_format);
|
||||||
|
|
||||||
GE( glGenTextures (1, &tex_2d->gl_texture) );
|
GE( glGenTextures (1, &tex_2d->gl_texture) );
|
||||||
_cogl_texture_driver_upload_to_gl (GL_TEXTURE_2D,
|
_cogl_texture_driver_upload_to_gl (GL_TEXTURE_2D,
|
||||||
tex_2d->gl_texture,
|
tex_2d->gl_texture,
|
||||||
&upload_data.bitmap,
|
&dst_bmp,
|
||||||
upload_data.gl_intformat,
|
gl_intformat,
|
||||||
upload_data.gl_format,
|
gl_format,
|
||||||
upload_data.gl_type);
|
gl_type);
|
||||||
|
|
||||||
tex_2d->gl_format = upload_data.gl_intformat;
|
tex_2d->gl_format = gl_intformat;
|
||||||
|
|
||||||
_cogl_texture_upload_data_free (&upload_data);
|
if (dst_bmp_owner)
|
||||||
|
g_free (dst_bmp.data);
|
||||||
|
|
||||||
return _cogl_texture_2d_handle_new (tex_2d);
|
return _cogl_texture_2d_handle_new (tex_2d);
|
||||||
}
|
}
|
||||||
@ -431,12 +432,10 @@ _cogl_texture_2d_set_region (CoglTexture *tex,
|
|||||||
CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex);
|
CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex);
|
||||||
gint bpp;
|
gint bpp;
|
||||||
CoglBitmap source_bmp;
|
CoglBitmap source_bmp;
|
||||||
CoglBitmap temp_bmp;
|
CoglBitmap tmp_bmp;
|
||||||
gboolean source_bmp_owner = FALSE;
|
gboolean tmp_bmp_owner = FALSE;
|
||||||
CoglPixelFormat closest_format;
|
|
||||||
GLenum closest_gl_format;
|
GLenum closest_gl_format;
|
||||||
GLenum closest_gl_type;
|
GLenum closest_gl_type;
|
||||||
gboolean success;
|
|
||||||
|
|
||||||
/* Check for valid format */
|
/* Check for valid format */
|
||||||
if (format == COGL_PIXEL_FORMAT_ANY)
|
if (format == COGL_PIXEL_FORMAT_ANY)
|
||||||
@ -456,39 +455,30 @@ _cogl_texture_2d_set_region (CoglTexture *tex,
|
|||||||
bpp = _cogl_get_format_bpp (format);
|
bpp = _cogl_get_format_bpp (format);
|
||||||
source_bmp.rowstride = (rowstride == 0) ? width * bpp : rowstride;
|
source_bmp.rowstride = (rowstride == 0) ? width * bpp : rowstride;
|
||||||
|
|
||||||
/* Find closest format to internal that's supported by GL */
|
/* Prepare the bitmap so that it will do the premultiplication
|
||||||
closest_format = _cogl_pixel_format_to_gl (tex_2d->format,
|
conversion */
|
||||||
NULL, /* don't need */
|
_cogl_texture_prepare_for_upload (&source_bmp,
|
||||||
|
tex_2d->format,
|
||||||
|
NULL,
|
||||||
|
&tmp_bmp,
|
||||||
|
&tmp_bmp_owner,
|
||||||
|
NULL,
|
||||||
&closest_gl_format,
|
&closest_gl_format,
|
||||||
&closest_gl_type);
|
&closest_gl_type);
|
||||||
|
|
||||||
/* If no direct match, convert */
|
|
||||||
if (closest_format != format)
|
|
||||||
{
|
|
||||||
/* Convert to required format */
|
|
||||||
success = _cogl_bitmap_convert_format_and_premult (&source_bmp,
|
|
||||||
&temp_bmp,
|
|
||||||
closest_format);
|
|
||||||
|
|
||||||
/* Swap bitmaps if succeeded */
|
|
||||||
if (!success) return FALSE;
|
|
||||||
source_bmp = temp_bmp;
|
|
||||||
source_bmp_owner = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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,
|
||||||
tex_2d->gl_texture,
|
tex_2d->gl_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,
|
||||||
&source_bmp,
|
&tmp_bmp,
|
||||||
closest_gl_format,
|
closest_gl_format,
|
||||||
closest_gl_type);
|
closest_gl_type);
|
||||||
|
|
||||||
/* Free data if owner */
|
/* Free data if owner */
|
||||||
if (source_bmp_owner)
|
if (tmp_bmp_owner)
|
||||||
g_free (source_bmp.data);
|
g_free (tmp_bmp.data);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,6 @@
|
|||||||
|
|
||||||
typedef struct _CoglTexture CoglTexture;
|
typedef struct _CoglTexture CoglTexture;
|
||||||
typedef struct _CoglTextureVtable CoglTextureVtable;
|
typedef struct _CoglTextureVtable CoglTextureVtable;
|
||||||
typedef struct _CoglTextureUploadData CoglTextureUploadData;
|
|
||||||
|
|
||||||
typedef void (*CoglTextureSliceCallback) (CoglHandle handle,
|
typedef void (*CoglTextureSliceCallback) (CoglHandle handle,
|
||||||
GLuint gl_handle,
|
GLuint gl_handle,
|
||||||
@ -107,17 +106,6 @@ struct _CoglTextureVtable
|
|||||||
gint (* get_height) (CoglTexture *tex);
|
gint (* get_height) (CoglTexture *tex);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This represents the state needed to upload texture data. There are
|
|
||||||
utility functions in cogl-texture which use this state */
|
|
||||||
struct _CoglTextureUploadData
|
|
||||||
{
|
|
||||||
CoglBitmap bitmap;
|
|
||||||
gboolean bitmap_owner;
|
|
||||||
GLenum gl_intformat;
|
|
||||||
GLenum gl_format;
|
|
||||||
GLenum gl_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _CoglTexture
|
struct _CoglTexture
|
||||||
{
|
{
|
||||||
CoglHandleObject _parent;
|
CoglHandleObject _parent;
|
||||||
@ -162,28 +150,20 @@ _cogl_texture_ensure_mipmaps (CoglHandle handle);
|
|||||||
void
|
void
|
||||||
_cogl_texture_ensure_non_quad_rendering (CoglHandle handle);
|
_cogl_texture_ensure_non_quad_rendering (CoglHandle handle);
|
||||||
|
|
||||||
/* Utility functions to help uploading a bitmap. These are intended to
|
/* Utility function to help uploading a bitmap. If the bitmap needs
|
||||||
* be used by CoglTexture implementations or drivers... */
|
premult conversion then it will be copied and *copied_bitmap will
|
||||||
|
be set to TRUE. Otherwise dst_bmp will be set to a shallow copy of
|
||||||
void
|
src_bmp. The GLenums needed for uploading are returned */
|
||||||
_cogl_texture_upload_data_free (CoglTextureUploadData *data);
|
|
||||||
|
|
||||||
void
|
|
||||||
_cogl_texture_upload_data_swap_bitmap (CoglTextureUploadData *data,
|
|
||||||
CoglBitmap *new_bitmap);
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
_cogl_texture_upload_data_prepare_format
|
_cogl_texture_prepare_for_upload (CoglBitmap *src_bmp,
|
||||||
(CoglTextureUploadData *data,
|
CoglPixelFormat dst_format,
|
||||||
CoglPixelFormat *internal_format);
|
CoglPixelFormat *dst_format_out,
|
||||||
|
CoglBitmap *dst_bmp,
|
||||||
gboolean
|
gboolean *copied_bitmap,
|
||||||
_cogl_texture_upload_data_convert (CoglTextureUploadData *data,
|
GLenum *out_glintformat,
|
||||||
CoglPixelFormat internal_format);
|
GLenum *out_glformat,
|
||||||
|
GLenum *out_gltype);
|
||||||
gboolean
|
|
||||||
_cogl_texture_upload_data_prepare (CoglTextureUploadData *data,
|
|
||||||
CoglPixelFormat internal_format);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_cogl_texture_prep_gl_alignment_for_pixels_upload (int pixels_rowstride);
|
_cogl_texture_prep_gl_alignment_for_pixels_upload (int pixels_rowstride);
|
||||||
|
@ -100,25 +100,71 @@ cogl_texture_unref (CoglHandle handle)
|
|||||||
cogl_handle_unref (handle);
|
cogl_handle_unref (handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
gboolean
|
||||||
_cogl_texture_upload_data_free (CoglTextureUploadData *data)
|
_cogl_texture_prepare_for_upload (CoglBitmap *src_bmp,
|
||||||
|
CoglPixelFormat dst_format,
|
||||||
|
CoglPixelFormat *dst_format_out,
|
||||||
|
CoglBitmap *dst_bmp,
|
||||||
|
gboolean *copied_bitmap,
|
||||||
|
GLenum *out_glintformat,
|
||||||
|
GLenum *out_glformat,
|
||||||
|
GLenum *out_gltype)
|
||||||
{
|
{
|
||||||
if (data->bitmap.data != NULL && data->bitmap_owner)
|
/* If the application hasn't specified a specific format then we'll
|
||||||
g_free (data->bitmap.data);
|
* pick the most appropriate. By default Cogl will use a
|
||||||
|
* premultiplied internal format. Later we will add control over
|
||||||
data->bitmap.data = NULL;
|
* this. */
|
||||||
data->bitmap_owner = FALSE;
|
if (dst_format == COGL_PIXEL_FORMAT_ANY)
|
||||||
|
{
|
||||||
|
if ((src_bmp->format & COGL_A_BIT) &&
|
||||||
|
src_bmp->format != COGL_PIXEL_FORMAT_A_8)
|
||||||
|
dst_format = src_bmp->format | COGL_PREMULT_BIT;
|
||||||
|
else
|
||||||
|
dst_format = src_bmp->format;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
if (dst_bmp)
|
||||||
_cogl_texture_upload_data_swap_bitmap (CoglTextureUploadData *data,
|
|
||||||
CoglBitmap *new_bitmap)
|
|
||||||
{
|
{
|
||||||
if (data->bitmap.data != NULL && data->bitmap_owner)
|
*copied_bitmap = FALSE;
|
||||||
g_free (data->bitmap.data);
|
*dst_bmp = *src_bmp;
|
||||||
|
|
||||||
data->bitmap = *new_bitmap;
|
/* If the source format does not have the same premult flag as the
|
||||||
data->bitmap_owner = TRUE;
|
dst format then we need to copy and convert it */
|
||||||
|
if ((src_bmp->format & COGL_A_BIT) &&
|
||||||
|
src_bmp->format != COGL_PIXEL_FORMAT_A_8 &&
|
||||||
|
(src_bmp->format & COGL_PREMULT_BIT) !=
|
||||||
|
(dst_format & COGL_PREMULT_BIT))
|
||||||
|
{
|
||||||
|
dst_bmp->data = g_memdup (dst_bmp->data,
|
||||||
|
dst_bmp->height * dst_bmp->rowstride);
|
||||||
|
*copied_bitmap = TRUE;
|
||||||
|
|
||||||
|
if (!_cogl_bitmap_convert_premult_status (dst_bmp,
|
||||||
|
src_bmp->format ^
|
||||||
|
COGL_PREMULT_BIT))
|
||||||
|
{
|
||||||
|
g_free (dst_bmp->data);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use the source format from the src bitmap type and the internal
|
||||||
|
format from the dst format type so that GL can do the
|
||||||
|
conversion */
|
||||||
|
_cogl_pixel_format_to_gl (src_bmp->format,
|
||||||
|
NULL, /* internal format */
|
||||||
|
out_glformat,
|
||||||
|
out_gltype);
|
||||||
|
_cogl_pixel_format_to_gl (dst_format,
|
||||||
|
out_glintformat,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (dst_format_out)
|
||||||
|
*dst_format_out = dst_format;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -157,64 +203,6 @@ _cogl_texture_set_wrap_mode_parameter (CoglHandle handle,
|
|||||||
tex->vtable->set_wrap_mode_parameter (tex, wrap_mode);
|
tex->vtable->set_wrap_mode_parameter (tex, wrap_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
|
||||||
_cogl_texture_upload_data_prepare_format
|
|
||||||
(CoglTextureUploadData *data,
|
|
||||||
CoglPixelFormat *internal_format)
|
|
||||||
{
|
|
||||||
/* Was there any internal conversion requested?
|
|
||||||
* By default Cogl will use a premultiplied internal format. Later we will
|
|
||||||
* add control over this. */
|
|
||||||
if (*internal_format == COGL_PIXEL_FORMAT_ANY)
|
|
||||||
{
|
|
||||||
if ((data->bitmap.format & COGL_A_BIT) &&
|
|
||||||
data->bitmap.format != COGL_PIXEL_FORMAT_A_8)
|
|
||||||
*internal_format = data->bitmap.format | COGL_PREMULT_BIT;
|
|
||||||
else
|
|
||||||
*internal_format = data->bitmap.format;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find closest format accepted by GL */
|
|
||||||
*internal_format = _cogl_pixel_format_to_gl (*internal_format,
|
|
||||||
&data->gl_intformat,
|
|
||||||
&data->gl_format,
|
|
||||||
&data->gl_type);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
_cogl_texture_upload_data_convert (CoglTextureUploadData *data,
|
|
||||||
CoglPixelFormat internal_format)
|
|
||||||
{
|
|
||||||
CoglBitmap new_bitmap;
|
|
||||||
gboolean success;
|
|
||||||
|
|
||||||
/* Convert to internal format */
|
|
||||||
if (internal_format != data->bitmap.format)
|
|
||||||
{
|
|
||||||
success = _cogl_bitmap_convert_format_and_premult (&data->bitmap,
|
|
||||||
&new_bitmap,
|
|
||||||
internal_format);
|
|
||||||
|
|
||||||
if (!success)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* Update texture with new data */
|
|
||||||
_cogl_texture_upload_data_swap_bitmap (data, &new_bitmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
_cogl_texture_upload_data_prepare (CoglTextureUploadData *data,
|
|
||||||
CoglPixelFormat internal_format)
|
|
||||||
{
|
|
||||||
return (_cogl_texture_upload_data_prepare_format (data, &internal_format) &&
|
|
||||||
_cogl_texture_upload_data_convert (data, internal_format));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This is like CoglSpanIter except it deals with floats and it
|
/* This is like CoglSpanIter except it deals with floats and it
|
||||||
effectively assumes there is only one span from 0.0 to 1.0 */
|
effectively assumes there is only one span from 0.0 to 1.0 */
|
||||||
typedef struct _CoglTextureIter
|
typedef struct _CoglTextureIter
|
||||||
|
Loading…
Reference in New Issue
Block a user