[cogl] texture: remove _cogl_texture_prepare_for_upload
- From: Robert Bragg <rbragg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [cogl] texture: remove _cogl_texture_prepare_for_upload
- Date: Thu, 11 Jul 2013 21:01:57 +0000 (UTC)
commit e190dd23c655da34b9c5c263a9f6006dcc0413b0
Author: Robert Bragg <robert linux intel com>
Date: Sat Jun 8 00:28:14 2013 +0100
texture: remove _cogl_texture_prepare_for_upload
This removes the gl centric _cogl_texture_prepare_for_upload api from
cogl-texture.c and instead adds a _cogl_bitmap_convert_for_upload() api
which everything now uses instead. GL specific code that needed the gl
internal/format/type enums returned by _cogl_texture_prepare_for_upload
now use ->pixel_format_to_gl directly.
Since there was a special case optimization in
cogl_texture_new_from_file that aimed to avoid copying the temporary
bitmap that's created for the given file and allow conversions to
happen in-place the new _cogl_bitmap_convert_for_upload() api supports
converting in place depending on a 'can_convert_in_place' argument.
This ability to convert bitmaps in-place has been integrated across the
different components as appropriate.
In updating cogl-texture-2d-sliced.c this was able to remove a number of
other GL specific parts to how spans are setup.
Reviewed-by: Neil Roberts <neil linux intel com>
cogl/cogl-atlas-texture-private.h | 1 +
cogl/cogl-atlas-texture.c | 70 +++++++-------
cogl/cogl-auto-texture.c | 55 ++++++-----
cogl/cogl-bitmap-conversion.c | 79 +++++++++++++++
cogl/cogl-bitmap-private.h | 6 +
cogl/cogl-driver.h | 1 +
cogl/cogl-texture-2d-private.h | 6 +
cogl/cogl-texture-2d-sliced-private.h | 1 +
cogl/cogl-texture-2d-sliced.c | 128 ++++++++++---------------
cogl/cogl-texture-2d.c | 16 +++-
cogl/cogl-texture-3d.c | 46 ++++++----
cogl/cogl-texture-private.h | 21 +----
cogl/cogl-texture-rectangle.c | 67 ++++++++-----
cogl/cogl-texture.c | 86 -----------------
cogl/cogl.symbols | 1 -
cogl/driver/gl/cogl-texture-2d-gl-private.h | 1 +
cogl/driver/gl/cogl-texture-2d-gl.c | 76 +++++++++------
cogl/driver/nop/cogl-texture-2d-nop-private.h | 1 +
cogl/driver/nop/cogl-texture-2d-nop.c | 1 +
19 files changed, 345 insertions(+), 318 deletions(-)
---
diff --git a/cogl/cogl-atlas-texture-private.h b/cogl/cogl-atlas-texture-private.h
index 670eea4..75c740e 100644
--- a/cogl/cogl-atlas-texture-private.h
+++ b/cogl/cogl-atlas-texture-private.h
@@ -61,6 +61,7 @@ CoglAtlasTexture *
_cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp,
CoglTextureFlags flags,
CoglPixelFormat internal_format,
+ CoglBool can_convert_in_place,
CoglError **error);
CoglAtlasTexture *
diff --git a/cogl/cogl-atlas-texture.c b/cogl/cogl-atlas-texture.c
index 747a6c9..b390cc2 100644
--- a/cogl/cogl-atlas-texture.c
+++ b/cogl/cogl-atlas-texture.c
@@ -510,12 +510,13 @@ _cogl_atlas_texture_set_region_with_border (CoglAtlasTexture *atlas_tex,
}
static CoglBitmap *
-_cogl_atlas_texture_prepare_for_upload (CoglAtlasTexture *atlas_tex,
- CoglBitmap *bmp,
- CoglError **error)
+_cogl_atlas_texture_convert_bitmap_for_upload (CoglAtlasTexture *atlas_tex,
+ CoglBitmap *bmp,
+ CoglBool can_convert_in_place,
+ CoglError **error)
{
CoglPixelFormat internal_format;
- CoglBitmap *converted_bmp;
+ CoglBitmap *upload_bmp;
CoglBitmap *override_bmp;
/* We'll prepare to upload using the format of the actual texture of
@@ -529,15 +530,11 @@ _cogl_atlas_texture_prepare_for_upload (CoglAtlasTexture *atlas_tex,
internal_format = (COGL_PIXEL_FORMAT_RGBA_8888 |
(atlas_tex->format & COGL_PREMULT_BIT));
- converted_bmp = _cogl_texture_prepare_for_upload (bmp,
- internal_format,
- NULL, /* dst_format_out */
- NULL, /* glintformat */
- NULL, /* glformat */
- NULL, /* gltype */
- error);
-
- if (converted_bmp == NULL)
+ upload_bmp = _cogl_bitmap_convert_for_upload (bmp,
+ internal_format,
+ can_convert_in_place,
+ error);
+ if (upload_bmp == NULL)
return NULL;
/* We'll create another bitmap which uses the same data but
@@ -545,14 +542,14 @@ _cogl_atlas_texture_prepare_for_upload (CoglAtlasTexture *atlas_tex,
to the atlas texture won't trigger the conversion again */
override_bmp =
- _cogl_bitmap_new_shared (converted_bmp,
- cogl_bitmap_get_format (converted_bmp) &
+ _cogl_bitmap_new_shared (upload_bmp,
+ cogl_bitmap_get_format (upload_bmp) &
~COGL_PREMULT_BIT,
- cogl_bitmap_get_width (converted_bmp),
- cogl_bitmap_get_height (converted_bmp),
- cogl_bitmap_get_rowstride (converted_bmp));
+ cogl_bitmap_get_width (upload_bmp),
+ cogl_bitmap_get_height (upload_bmp),
+ cogl_bitmap_get_rowstride (upload_bmp));
- cogl_object_unref (converted_bmp);
+ cogl_object_unref (upload_bmp);
return override_bmp;
}
@@ -579,11 +576,13 @@ _cogl_atlas_texture_set_region (CoglTexture *tex,
if (atlas_tex->atlas)
{
CoglBool ret;
-
- bmp = _cogl_atlas_texture_prepare_for_upload (atlas_tex,
- bmp,
- error);
- if (!bmp)
+ CoglBitmap *upload_bmp =
+ _cogl_atlas_texture_convert_bitmap_for_upload (atlas_tex,
+ bmp,
+ FALSE, /* can't convert
+ in place */
+ error);
+ if (!upload_bmp)
return FALSE;
/* Upload the data ignoring the premult bit */
@@ -591,10 +590,10 @@ _cogl_atlas_texture_set_region (CoglTexture *tex,
src_x, src_y,
dst_x, dst_y,
dst_width, dst_height,
- bmp,
+ upload_bmp,
error);
- cogl_object_unref (bmp);
+ cogl_object_unref (upload_bmp);
return ret;
}
@@ -788,11 +787,12 @@ CoglAtlasTexture *
_cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp,
CoglTextureFlags flags,
CoglPixelFormat internal_format,
+ CoglBool can_convert_in_place,
CoglError **error)
{
CoglContext *ctx = _cogl_bitmap_get_context (bmp);
CoglAtlasTexture *atlas_tex;
- CoglBitmap *dst_bmp;
+ CoglBitmap *upload_bmp;
int bmp_width;
int bmp_height;
CoglPixelFormat bmp_format;
@@ -819,10 +819,12 @@ _cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp,
return NULL;
}
- dst_bmp = _cogl_atlas_texture_prepare_for_upload (atlas_tex,
- bmp,
- error);
- if (dst_bmp == NULL)
+ upload_bmp =
+ _cogl_atlas_texture_convert_bitmap_for_upload (atlas_tex,
+ bmp,
+ can_convert_in_place,
+ error);
+ if (upload_bmp == NULL)
{
cogl_object_unref (atlas_tex);
return NULL;
@@ -837,15 +839,15 @@ _cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp,
0, /* dst_y */
bmp_width, /* dst_width */
bmp_height, /* dst_height */
- dst_bmp,
+ upload_bmp,
error))
{
- cogl_object_unref (dst_bmp);
+ cogl_object_unref (upload_bmp);
cogl_object_unref (atlas_tex);
return NULL;
}
- cogl_object_unref (dst_bmp);
+ cogl_object_unref (upload_bmp);
return atlas_tex;
}
diff --git a/cogl/cogl-auto-texture.c b/cogl/cogl-auto-texture.c
index 402cfb9..166e6a5 100644
--- a/cogl/cogl-auto-texture.c
+++ b/cogl/cogl-auto-texture.c
@@ -34,6 +34,7 @@
#include "cogl-texture.h"
#include "cogl-util.h"
#include "cogl-texture-2d.h"
+#include "cogl-texture-2d-private.h"
#include "cogl-primitive-texture.h"
#include "cogl-texture-2d-sliced-private.h"
#include "cogl-private.h"
@@ -134,11 +135,12 @@ cogl_texture_new_from_data (CoglContext *ctx,
return tex;
}
-CoglTexture *
-cogl_texture_new_from_bitmap (CoglBitmap *bitmap,
- CoglTextureFlags flags,
- CoglPixelFormat internal_format,
- CoglError **error)
+static CoglTexture *
+_cogl_texture_new_from_bitmap (CoglBitmap *bitmap,
+ CoglTextureFlags flags,
+ CoglPixelFormat internal_format,
+ CoglBool can_convert_in_place,
+ CoglError **error)
{
CoglContext *ctx = _cogl_bitmap_get_context (bitmap);
CoglAtlasTexture *atlas_tex;
@@ -149,6 +151,7 @@ cogl_texture_new_from_bitmap (CoglBitmap *bitmap,
if ((atlas_tex = _cogl_atlas_texture_new_from_bitmap (bitmap,
flags,
internal_format,
+ can_convert_in_place,
&internal_error)))
return COGL_TEXTURE (atlas_tex);
@@ -161,9 +164,10 @@ cogl_texture_new_from_bitmap (CoglBitmap *bitmap,
(cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_BASIC) &&
cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP)))
{
- tex = COGL_TEXTURE (cogl_texture_2d_new_from_bitmap (bitmap,
- internal_format,
- &internal_error));
+ tex = COGL_TEXTURE (_cogl_texture_2d_new_from_bitmap (bitmap,
+ internal_format,
+ can_convert_in_place,
+ &internal_error));
if (!tex)
{
@@ -186,6 +190,7 @@ cogl_texture_new_from_bitmap (CoglBitmap *bitmap,
tex = COGL_TEXTURE (_cogl_texture_2d_sliced_new_from_bitmap (bitmap,
flags,
internal_format,
+ can_convert_in_place,
error));
}
@@ -193,6 +198,19 @@ cogl_texture_new_from_bitmap (CoglBitmap *bitmap,
}
CoglTexture *
+cogl_texture_new_from_bitmap (CoglBitmap *bitmap,
+ CoglTextureFlags flags,
+ CoglPixelFormat internal_format,
+ CoglError **error)
+{
+ return _cogl_texture_new_from_bitmap (bitmap,
+ flags,
+ internal_format,
+ FALSE, /* can't convert in-place */
+ error);
+}
+
+CoglTexture *
cogl_texture_new_from_file (CoglContext *ctx,
const char *filename,
CoglTextureFlags flags,
@@ -201,7 +219,6 @@ cogl_texture_new_from_file (CoglContext *ctx,
{
CoglBitmap *bmp;
CoglTexture *texture = NULL;
- CoglPixelFormat src_format;
_COGL_RETURN_VAL_IF_FAIL (error == NULL || *error == NULL, NULL);
@@ -209,22 +226,10 @@ cogl_texture_new_from_file (CoglContext *ctx,
if (bmp == NULL)
return NULL;
- src_format = cogl_bitmap_get_format (bmp);
-
- /* We know that the bitmap data is solely owned by this function so
- we can do the premult conversion in place. This avoids having to
- copy the bitmap which will otherwise happen in
- _cogl_texture_prepare_for_upload */
- internal_format =
- _cogl_texture_determine_internal_format (src_format, internal_format);
- if (!_cogl_texture_needs_premult_conversion (src_format, internal_format) ||
- _cogl_bitmap_convert_premult_status (bmp,
- src_format ^ COGL_PREMULT_BIT,
- error))
- {
- texture =
- cogl_texture_new_from_bitmap (bmp, flags, internal_format, error);
- }
+ texture = _cogl_texture_new_from_bitmap (bmp, flags,
+ internal_format,
+ TRUE, /* can convert in-place */
+ error);
cogl_object_unref (bmp);
diff --git a/cogl/cogl-bitmap-conversion.c b/cogl/cogl-bitmap-conversion.c
index 102bf23..7bc2f1d 100644
--- a/cogl/cogl-bitmap-conversion.c
+++ b/cogl/cogl-bitmap-conversion.c
@@ -504,6 +504,85 @@ _cogl_bitmap_convert (CoglBitmap *src_bmp,
return dst_bmp;
}
+CoglBitmap *
+_cogl_bitmap_convert_for_upload (CoglBitmap *src_bmp,
+ CoglPixelFormat internal_format,
+ CoglBool can_convert_in_place,
+ CoglError **error)
+{
+ CoglContext *ctx = _cogl_bitmap_get_context (src_bmp);
+ CoglPixelFormat src_format = cogl_bitmap_get_format (src_bmp);
+ CoglBitmap *dst_bmp;
+
+ _COGL_RETURN_VAL_IF_FAIL (internal_format != COGL_PIXEL_FORMAT_ANY, NULL);
+
+ /* OpenGL supports specifying a different format for the internal
+ format when uploading texture data. We should use this to convert
+ formats because it is likely to be faster and support more types
+ than the Cogl bitmap code. However under GLES the internal format
+ must be the same as the bitmap format and it only supports a
+ limited number of formats so we must convert using the Cogl
+ bitmap code instead */
+
+ /* If the driver doesn't natively support alpha textures then it
+ * won't work correctly to convert to/from component-alpha
+ * textures */
+
+ if ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_FORMAT_CONVERSION) &&
+ ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_ALPHA_TEXTURES) ||
+ (src_format != COGL_PIXEL_FORMAT_A_8 &&
+ internal_format != COGL_PIXEL_FORMAT_A_8) ||
+ src_format == internal_format))
+ {
+ /* If the source format does not have the same premult flag as the
+ internal_format then we need to copy and convert it */
+ if (_cogl_texture_needs_premult_conversion (src_format,
+ internal_format))
+ {
+ if (can_convert_in_place)
+ {
+ if (_cogl_bitmap_convert_premult_status (src_bmp,
+ (src_format ^
+ COGL_PREMULT_BIT),
+ error))
+ {
+ dst_bmp = cogl_object_ref (src_bmp);
+ }
+ else
+ return NULL;
+ }
+ else
+ {
+ dst_bmp = _cogl_bitmap_convert (src_bmp,
+ src_format ^ COGL_PREMULT_BIT,
+ error);
+ if (dst_bmp == NULL)
+ return NULL;
+ }
+ }
+ else
+ dst_bmp = cogl_object_ref (src_bmp);
+ }
+ else
+ {
+ CoglPixelFormat closest_format;
+
+ closest_format =
+ ctx->driver_vtable->pixel_format_to_gl (ctx,
+ internal_format,
+ NULL, /* ignore gl intformat */
+ NULL, /* ignore gl format */
+ NULL); /* ignore gl type */
+
+ if (closest_format != src_format)
+ dst_bmp = _cogl_bitmap_convert (src_bmp, closest_format, error);
+ else
+ dst_bmp = cogl_object_ref (src_bmp);
+ }
+
+ return dst_bmp;
+}
+
CoglBool
_cogl_bitmap_unpremult (CoglBitmap *bmp,
CoglError **error)
diff --git a/cogl/cogl-bitmap-private.h b/cogl/cogl-bitmap-private.h
index ae96aaf..34ad4cf 100644
--- a/cogl/cogl-bitmap-private.h
+++ b/cogl/cogl-bitmap-private.h
@@ -105,6 +105,12 @@ _cogl_bitmap_convert (CoglBitmap *bmp,
CoglPixelFormat dst_format,
CoglError **error);
+CoglBitmap *
+_cogl_bitmap_convert_for_upload (CoglBitmap *src_bmp,
+ CoglPixelFormat internal_format,
+ CoglBool can_convert_in_place,
+ CoglError **error);
+
CoglBool
_cogl_bitmap_convert_into_bitmap (CoglBitmap *src_bmp,
CoglBitmap *dst_bmp,
diff --git a/cogl/cogl-driver.h b/cogl/cogl-driver.h
index e90e6fa..4642236 100644
--- a/cogl/cogl-driver.h
+++ b/cogl/cogl-driver.h
@@ -148,6 +148,7 @@ struct _CoglDriverVtable
CoglTexture2D *
(* texture_2d_new_from_bitmap) (CoglBitmap *bmp,
CoglPixelFormat internal_format,
+ CoglBool can_convert_in_place,
CoglError **error);
#if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base)
diff --git a/cogl/cogl-texture-2d-private.h b/cogl/cogl-texture-2d-private.h
index 12e5820..5d193bc 100644
--- a/cogl/cogl-texture-2d-private.h
+++ b/cogl/cogl-texture-2d-private.h
@@ -59,6 +59,12 @@ struct _CoglTexture2D
CoglTexturePixel first_pixel;
};
+CoglTexture2D *
+_cogl_texture_2d_new_from_bitmap (CoglBitmap *bmp,
+ CoglPixelFormat internal_format,
+ CoglBool can_convert_in_place,
+ CoglError **error);
+
#if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base)
/* NB: The reason we require the width, height and format to be passed
* even though they may seem redundant is because GLES 1/2 don't
diff --git a/cogl/cogl-texture-2d-sliced-private.h b/cogl/cogl-texture-2d-sliced-private.h
index fbfd198..2d5106f 100644
--- a/cogl/cogl-texture-2d-sliced-private.h
+++ b/cogl/cogl-texture-2d-sliced-private.h
@@ -56,6 +56,7 @@ CoglTexture2DSliced *
_cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp,
CoglTextureFlags flags,
CoglPixelFormat internal_format,
+ CoglBool can_convert_in_place,
CoglError **error);
#endif /* __COGL_TEXTURE_2D_SLICED_PRIVATE_H */
diff --git a/cogl/cogl-texture-2d-sliced.c b/cogl/cogl-texture-2d-sliced.c
index 6189214..88e0553 100644
--- a/cogl/cogl-texture-2d-sliced.c
+++ b/cogl/cogl-texture-2d-sliced.c
@@ -332,9 +332,9 @@ _cogl_texture_2d_sliced_set_waste (CoglTexture2DSliced *tex_2ds,
}
static CoglBool
-_cogl_texture_2d_sliced_upload_to_gl (CoglTexture2DSliced *tex_2ds,
- CoglBitmap *bmp,
- CoglError **error)
+_cogl_texture_2d_sliced_upload_bitmap (CoglTexture2DSliced *tex_2ds,
+ CoglBitmap *bmp,
+ CoglError **error)
{
CoglSpan *x_span;
CoglSpan *y_span;
@@ -422,17 +422,15 @@ _cogl_texture_2d_sliced_upload_to_gl (CoglTexture2DSliced *tex_2ds,
}
static CoglBool
-_cogl_texture_2d_sliced_upload_subregion_to_gl (CoglTexture2DSliced *tex_2ds,
- int src_x,
- int src_y,
- int dst_x,
- int dst_y,
- int width,
- int height,
- CoglBitmap *source_bmp,
- GLuint source_gl_format,
- GLuint source_gl_type,
- CoglError **error)
+_cogl_texture_2d_sliced_upload_subregion (CoglTexture2DSliced *tex_2ds,
+ int src_x,
+ int src_y,
+ int dst_x,
+ int dst_y,
+ int width,
+ int height,
+ CoglBitmap *source_bmp,
+ CoglError **error)
{
CoglTexture *tex = COGL_TEXTURE (tex_2ds);
CoglSpan *x_span;
@@ -667,16 +665,13 @@ _cogl_texture_2d_sliced_setup_spans (CoglContext *ctx,
int width,
int height,
int max_waste,
- CoglPixelFormat format,
+ CoglPixelFormat internal_format,
CoglError **error)
{
int max_width;
int max_height;
int n_x_slices;
int n_y_slices;
- GLenum gl_intformat;
- GLenum gl_format;
- GLenum gl_type;
int (*slices_for_size) (int, int, int, GArray*);
@@ -694,25 +689,16 @@ _cogl_texture_2d_sliced_setup_spans (CoglContext *ctx,
slices_for_size = _cogl_pot_slices_for_size;
}
- ctx->driver_vtable->pixel_format_to_gl (ctx,
- format,
- &gl_intformat,
- &gl_format,
- &gl_type);
-
/* Negative number means no slicing forced by the user */
if (max_waste <= -1)
{
CoglSpan span;
/* Check if size supported else bail out */
- if (!ctx->texture_driver->size_supported (ctx,
- GL_TEXTURE_2D,
- gl_intformat,
- gl_format,
- gl_type,
- max_width,
- max_height))
+ if (!ctx->driver_vtable->texture_2d_can_create (ctx,
+ max_width,
+ max_height,
+ internal_format))
{
_cogl_set_error (error,
COGL_TEXTURE_ERROR,
@@ -749,13 +735,10 @@ _cogl_texture_2d_sliced_setup_spans (CoglContext *ctx,
else
{
/* Decrease the size of largest slice until supported by GL */
- while (!ctx->texture_driver->size_supported (ctx,
- GL_TEXTURE_2D,
- gl_intformat,
- gl_format,
- gl_type,
- max_width,
- max_height))
+ while (!ctx->driver_vtable->texture_2d_can_create (ctx,
+ max_width,
+ max_height,
+ internal_format))
{
/* Alternate between width and height */
if (max_width > max_height)
@@ -975,14 +958,12 @@ CoglTexture2DSliced *
_cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp,
CoglTextureFlags flags,
CoglPixelFormat internal_format,
+ CoglBool can_convert_in_place,
CoglError **error)
{
CoglContext *ctx;
CoglTexture2DSliced *tex_2ds;
- CoglBitmap *dst_bmp;
- GLenum gl_intformat;
- GLenum gl_format;
- GLenum gl_type;
+ CoglBitmap *upload_bmp;
int width, height, max_waste;
int i;
@@ -1001,14 +982,15 @@ _cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp,
else
max_waste = COGL_TEXTURE_MAX_WASTE;
- dst_bmp = _cogl_texture_prepare_for_upload (bmp,
- internal_format,
- &internal_format,
- &gl_intformat,
- &gl_format,
- &gl_type,
- error);
- if (dst_bmp == NULL)
+ internal_format =
+ _cogl_texture_determine_internal_format (cogl_bitmap_get_format (bmp),
+ internal_format);
+
+ upload_bmp = _cogl_bitmap_convert_for_upload (bmp,
+ internal_format,
+ can_convert_in_place,
+ error);
+ if (upload_bmp == NULL)
{
_cogl_texture_2d_sliced_free (tex_2ds);
return NULL;
@@ -1027,12 +1009,12 @@ _cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp,
if (!cogl_texture_allocate (COGL_TEXTURE (tex_2ds), error))
goto error;
- if (!_cogl_texture_2d_sliced_upload_to_gl (tex_2ds,
- dst_bmp,
- error))
+ if (!_cogl_texture_2d_sliced_upload_bitmap (tex_2ds,
+ upload_bmp,
+ error))
goto error;
- cogl_object_unref (dst_bmp);
+ cogl_object_unref (upload_bmp);
if ((flags & COGL_TEXTURE_NO_AUTO_MIPMAP))
for (i = 0; i < tex_2ds->slice_textures->len; i++)
@@ -1049,7 +1031,7 @@ _cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp,
return _cogl_texture_2d_sliced_object_new (tex_2ds);
error:
- cogl_object_unref (dst_bmp);
+ cogl_object_unref (upload_bmp);
_cogl_texture_2d_sliced_free (tex_2ds);
return NULL;
}
@@ -1351,32 +1333,24 @@ _cogl_texture_2d_sliced_set_region (CoglTexture *tex,
CoglError **error)
{
CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex);
- GLenum gl_format;
- GLenum gl_type;
+ CoglBitmap *upload_bmp;
CoglBool status;
- bmp = _cogl_texture_prepare_for_upload (bmp,
- cogl_texture_get_format (tex),
- NULL,
- NULL,
- &gl_format,
- &gl_type,
- error);
- if (!bmp)
+ upload_bmp = _cogl_bitmap_convert_for_upload (bmp,
+ cogl_texture_get_format (tex),
+ FALSE, /* can't convert in
+ place */
+ error);
+ if (!upload_bmp)
return FALSE;
- /* Send data to GL */
- status =
- _cogl_texture_2d_sliced_upload_subregion_to_gl (tex_2ds,
- src_x, src_y,
- dst_x, dst_y,
- dst_width, dst_height,
- bmp,
- gl_format,
- gl_type,
- error);
-
- cogl_object_unref (bmp);
+ status = _cogl_texture_2d_sliced_upload_subregion (tex_2ds,
+ src_x, src_y,
+ dst_x, dst_y,
+ dst_width, dst_height,
+ upload_bmp,
+ error);
+ cogl_object_unref (upload_bmp);
return status;
}
diff --git a/cogl/cogl-texture-2d.c b/cogl/cogl-texture-2d.c
index d253bad..bd511bb 100644
--- a/cogl/cogl-texture-2d.c
+++ b/cogl/cogl-texture-2d.c
@@ -150,9 +150,10 @@ _cogl_texture_2d_allocate (CoglTexture *tex,
}
CoglTexture2D *
-cogl_texture_2d_new_from_bitmap (CoglBitmap *bmp,
- CoglPixelFormat internal_format,
- CoglError **error)
+_cogl_texture_2d_new_from_bitmap (CoglBitmap *bmp,
+ CoglPixelFormat internal_format,
+ CoglBool can_convert_in_place,
+ CoglError **error)
{
CoglContext *ctx;
@@ -178,10 +179,19 @@ cogl_texture_2d_new_from_bitmap (CoglBitmap *bmp,
return ctx->driver_vtable->texture_2d_new_from_bitmap (bmp,
internal_format,
+ can_convert_in_place,
error);
}
CoglTexture2D *
+cogl_texture_2d_new_from_bitmap (CoglBitmap *bmp,
+ CoglPixelFormat internal_format,
+ CoglError **error)
+{
+ return _cogl_texture_2d_new_from_bitmap (bmp, internal_format, FALSE, error);
+}
+
+CoglTexture2D *
cogl_texture_2d_new_from_data (CoglContext *ctx,
int width,
int height,
diff --git a/cogl/cogl-texture-3d.c b/cogl/cogl-texture-3d.c
index 7f29549..83f85c1 100644
--- a/cogl/cogl-texture-3d.c
+++ b/cogl/cogl-texture-3d.c
@@ -279,8 +279,9 @@ cogl_texture_3d_new_from_bitmap (CoglBitmap *bmp,
CoglError **error)
{
CoglTexture3D *tex_3d;
- CoglBitmap *dst_bmp;
+ CoglBitmap *upload_bmp;
CoglPixelFormat bmp_format;
+ CoglPixelFormat upload_format;
unsigned int bmp_width;
GLenum gl_intformat;
GLenum gl_format;
@@ -301,16 +302,27 @@ cogl_texture_3d_new_from_bitmap (CoglBitmap *bmp,
error))
return NULL;
- dst_bmp = _cogl_texture_prepare_for_upload (bmp,
- internal_format,
- &internal_format,
- &gl_intformat,
- &gl_format,
- &gl_type,
- error);
- if (dst_bmp == NULL)
+ upload_bmp =
+ _cogl_bitmap_convert_for_upload (bmp,
+ internal_format,
+ FALSE, /* can't convert in place */
+ error);
+ if (upload_bmp == NULL)
return NULL;
+ upload_format = cogl_bitmap_get_format (upload_bmp);
+
+ ctx->driver_vtable->pixel_format_to_gl (ctx,
+ upload_format,
+ NULL, /* internal format */
+ &gl_format,
+ &gl_type);
+ ctx->driver_vtable->pixel_format_to_gl (ctx,
+ internal_format,
+ &gl_intformat,
+ NULL,
+ NULL);
+
tex_3d = _cogl_texture_3d_create_base (ctx,
bmp_width, height, depth,
internal_format);
@@ -320,20 +332,18 @@ cogl_texture_3d_new_from_bitmap (CoglBitmap *bmp,
if (!cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN))
{
CoglError *ignore = NULL;
- uint8_t *data = _cogl_bitmap_map (dst_bmp,
+ uint8_t *data = _cogl_bitmap_map (upload_bmp,
COGL_BUFFER_ACCESS_READ, 0,
&ignore);
- CoglPixelFormat format = cogl_bitmap_get_format (dst_bmp);
-
tex_3d->first_pixel.gl_format = gl_format;
tex_3d->first_pixel.gl_type = gl_type;
if (data)
{
memcpy (tex_3d->first_pixel.data, data,
- _cogl_pixel_format_get_bytes_per_pixel (format));
- _cogl_bitmap_unmap (dst_bmp);
+ _cogl_pixel_format_get_bytes_per_pixel (upload_format));
+ _cogl_bitmap_unmap (upload_bmp);
}
else
{
@@ -341,7 +351,7 @@ cogl_texture_3d_new_from_bitmap (CoglBitmap *bmp,
"glGenerateMipmap fallback");
cogl_error_free (ignore);
memset (tex_3d->first_pixel.data, 0,
- _cogl_pixel_format_get_bytes_per_pixel (format));
+ _cogl_pixel_format_get_bytes_per_pixel (upload_format));
}
}
@@ -354,20 +364,20 @@ cogl_texture_3d_new_from_bitmap (CoglBitmap *bmp,
FALSE, /* is_foreign */
height,
depth,
- dst_bmp,
+ upload_bmp,
gl_intformat,
gl_format,
gl_type,
error))
{
- cogl_object_unref (dst_bmp);
+ cogl_object_unref (upload_bmp);
cogl_object_unref (tex_3d);
return NULL;
}
tex_3d->gl_format = gl_intformat;
- cogl_object_unref (dst_bmp);
+ cogl_object_unref (upload_bmp);
_cogl_texture_set_allocated (COGL_TEXTURE (tex_3d), TRUE);
diff --git a/cogl/cogl-texture-private.h b/cogl/cogl-texture-private.h
index 2dfbf20..1f7476f 100644
--- a/cogl/cogl-texture-private.h
+++ b/cogl/cogl-texture-private.h
@@ -65,9 +65,9 @@ struct _CoglTextureVtable
/* This should update the specified sub region of the texture with a
sub region of the given bitmap. The bitmap is not converted
- before being passed so the implementation is expected to call
- _cogl_texture_prepare_for_upload with a suitable destination
- format before uploading */
+ before being set so the caller is expected to have called
+ _cogl_bitmap_convert_for_upload with a suitable internal_format
+ before passing here */
CoglBool (* set_region) (CoglTexture *tex,
int src_x,
int src_y,
@@ -225,21 +225,6 @@ CoglPixelFormat
_cogl_texture_determine_internal_format (CoglPixelFormat src_format,
CoglPixelFormat dst_format);
-/* Utility function to help uploading a bitmap. If the bitmap needs
- * premult conversion then a converted copy will be returned,
- * otherwise a reference to the original source will be returned.
- *
- * The GLenums needed for uploading are returned
- */
-CoglBitmap *
-_cogl_texture_prepare_for_upload (CoglBitmap *src_bmp,
- CoglPixelFormat dst_format,
- CoglPixelFormat *dst_format_out,
- GLenum *out_glintformat,
- GLenum *out_glformat,
- GLenum *out_gltype,
- CoglError **error);
-
CoglBool
_cogl_texture_is_foreign (CoglTexture *texture);
diff --git a/cogl/cogl-texture-rectangle.c b/cogl/cogl-texture-rectangle.c
index f81ecab..d006085 100644
--- a/cogl/cogl-texture-rectangle.c
+++ b/cogl/cogl-texture-rectangle.c
@@ -261,11 +261,11 @@ cogl_texture_rectangle_new_from_bitmap (CoglBitmap *bmp,
CoglError **error)
{
CoglTextureRectangle *tex_rect;
- CoglBitmap *dst_bmp;
- GLenum gl_intformat;
- GLenum gl_format;
- GLenum gl_type;
- CoglContext *ctx;
+ CoglBitmap *upload_bmp;
+ GLenum gl_intformat;
+ GLenum gl_format;
+ GLenum gl_type;
+ CoglContext *ctx;
_COGL_RETURN_VAL_IF_FAIL (cogl_is_bitmap (bmp), NULL);
@@ -282,17 +282,25 @@ cogl_texture_rectangle_new_from_bitmap (CoglBitmap *bmp,
error))
return NULL;
- dst_bmp = _cogl_texture_prepare_for_upload (bmp,
- internal_format,
- &internal_format,
- &gl_intformat,
- &gl_format,
- &gl_type,
- error);
-
- if (dst_bmp == NULL)
+ upload_bmp =
+ _cogl_bitmap_convert_for_upload (bmp,
+ internal_format,
+ FALSE, /* can't convert in place */
+ error);
+ if (upload_bmp == NULL)
return NULL;
+ ctx->driver_vtable->pixel_format_to_gl (ctx,
+ cogl_bitmap_get_format (upload_bmp),
+ NULL, /* internal format */
+ &gl_format,
+ &gl_type);
+ ctx->driver_vtable->pixel_format_to_gl (ctx,
+ internal_format,
+ &gl_intformat,
+ NULL,
+ NULL);
+
tex_rect = _cogl_texture_rectangle_create_base (ctx,
cogl_bitmap_get_width (bmp),
cogl_bitmap_get_height (bmp),
@@ -306,20 +314,20 @@ cogl_texture_rectangle_new_from_bitmap (CoglBitmap *bmp,
GL_TEXTURE_RECTANGLE_ARB,
tex_rect->gl_texture,
FALSE,
- dst_bmp,
+ upload_bmp,
gl_intformat,
gl_format,
gl_type,
error))
{
- cogl_object_unref (dst_bmp);
+ cogl_object_unref (upload_bmp);
cogl_object_unref (tex_rect);
return NULL;
}
tex_rect->gl_format = gl_intformat;
- cogl_object_unref (dst_bmp);
+ cogl_object_unref (upload_bmp);
_cogl_texture_set_allocated (COGL_TEXTURE (tex_rect), TRUE);
@@ -564,21 +572,26 @@ _cogl_texture_rectangle_set_region (CoglTexture *tex,
CoglBitmap *bmp,
CoglError **error)
{
+ CoglBitmap *upload_bmp;
GLenum gl_format;
GLenum gl_type;
CoglContext *ctx = tex->context;
CoglBool status;
- bmp = _cogl_texture_prepare_for_upload (bmp,
- cogl_texture_get_format (tex),
- NULL,
- NULL,
- &gl_format,
- &gl_type,
- error);
- if (!bmp)
+ upload_bmp =
+ _cogl_bitmap_convert_for_upload (bmp,
+ cogl_texture_get_format (tex),
+ FALSE, /* can't convert in place */
+ error);
+ if (upload_bmp == NULL)
return FALSE;
+ ctx->driver_vtable->pixel_format_to_gl (ctx,
+ cogl_bitmap_get_format (upload_bmp),
+ NULL, /* internal format */
+ &gl_format,
+ &gl_type);
+
/* Send data to GL */
status =
ctx->texture_driver->upload_subregion_to_gl (ctx,
@@ -588,12 +601,12 @@ _cogl_texture_rectangle_set_region (CoglTexture *tex,
dst_x, dst_y,
dst_width, dst_height,
level,
- bmp,
+ upload_bmp,
gl_format,
gl_type,
error);
- cogl_object_unref (bmp);
+ cogl_object_unref (upload_bmp);
return status;
}
diff --git a/cogl/cogl-texture.c b/cogl/cogl-texture.c
index 2c7dc5e..64398f4 100644
--- a/cogl/cogl-texture.c
+++ b/cogl/cogl-texture.c
@@ -161,92 +161,6 @@ _cogl_texture_determine_internal_format (CoglPixelFormat src_format,
return dst_format;
}
-CoglBitmap *
-_cogl_texture_prepare_for_upload (CoglBitmap *src_bmp,
- CoglPixelFormat dst_format,
- CoglPixelFormat *dst_format_out,
- GLenum *out_glintformat,
- GLenum *out_glformat,
- GLenum *out_gltype,
- CoglError **error)
-{
- CoglContext *ctx = _cogl_bitmap_get_context (src_bmp);
- CoglPixelFormat src_format = cogl_bitmap_get_format (src_bmp);
- CoglBitmap *dst_bmp;
-
- dst_format = _cogl_texture_determine_internal_format (src_format,
- dst_format);
-
- /* OpenGL supports specifying a different format for the internal
- format when uploading texture data. We should use this to convert
- formats because it is likely to be faster and support more types
- than the Cogl bitmap code. However under GLES the internal format
- must be the same as the bitmap format and it only supports a
- limited number of formats so we must convert using the Cogl
- bitmap code instead */
-
- /* If the driver doesn't natively support alpha textures then it
- * won't work correctly to convert to/from component-alpha
- * textures */
-
- if ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_FORMAT_CONVERSION) &&
- ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_ALPHA_TEXTURES) ||
- (src_format != COGL_PIXEL_FORMAT_A_8 &&
- dst_format != COGL_PIXEL_FORMAT_A_8) ||
- src_format == dst_format))
- {
- /* If the source format does not have the same premult flag as the
- dst format then we need to copy and convert it */
- if (_cogl_texture_needs_premult_conversion (src_format,
- dst_format))
- {
- dst_bmp = _cogl_bitmap_convert (src_bmp,
- src_format ^ COGL_PREMULT_BIT,
- error);
-
- if (dst_bmp == NULL)
- return NULL;
- }
- else
- dst_bmp = cogl_object_ref (src_bmp);
-
- /* 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 */
- ctx->driver_vtable->pixel_format_to_gl (ctx,
- src_format,
- NULL, /* internal format */
- out_glformat,
- out_gltype);
- ctx->driver_vtable->pixel_format_to_gl (ctx,
- dst_format,
- out_glintformat,
- NULL,
- NULL);
-
- }
- else
- {
- CoglPixelFormat closest_format;
-
- closest_format = ctx->driver_vtable->pixel_format_to_gl (ctx,
- dst_format,
- out_glintformat,
- out_glformat,
- out_gltype);
-
- if (closest_format != src_format)
- dst_bmp = _cogl_bitmap_convert (src_bmp, closest_format, error);
- else
- dst_bmp = cogl_object_ref (src_bmp);
- }
-
- if (dst_format_out)
- *dst_format_out = dst_format;
-
- return dst_bmp;
-}
-
CoglBool
_cogl_texture_is_foreign (CoglTexture *texture)
{
diff --git a/cogl/cogl.symbols b/cogl/cogl.symbols
index 714ef15..89a2bd8 100644
--- a/cogl/cogl.symbols
+++ b/cogl/cogl.symbols
@@ -663,7 +663,6 @@ _cogl_texture_get_associated_framebuffers
_cogl_texture_get_gl_format
_cogl_texture_init
_cogl_texture_is_foreign
-_cogl_texture_prepare_for_upload
_cogl_texture_gl_prep_alignment_for_pixels_upload
_cogl_texture_pre_paint
_cogl_texture_register_texture_type
diff --git a/cogl/driver/gl/cogl-texture-2d-gl-private.h b/cogl/driver/gl/cogl-texture-2d-gl-private.h
index c71908f..0bab9e2 100644
--- a/cogl/driver/gl/cogl-texture-2d-gl-private.h
+++ b/cogl/driver/gl/cogl-texture-2d-gl-private.h
@@ -51,6 +51,7 @@ _cogl_texture_2d_gl_allocate (CoglTexture *tex,
CoglTexture2D *
_cogl_texture_2d_gl_new_from_bitmap (CoglBitmap *bmp,
CoglPixelFormat internal_format,
+ CoglBool can_convert_in_place,
CoglError **error);
#if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base)
diff --git a/cogl/driver/gl/cogl-texture-2d-gl.c b/cogl/driver/gl/cogl-texture-2d-gl.c
index a8a51a4..a793b9f 100644
--- a/cogl/driver/gl/cogl-texture-2d-gl.c
+++ b/cogl/driver/gl/cogl-texture-2d-gl.c
@@ -151,25 +151,34 @@ _cogl_texture_2d_gl_allocate (CoglTexture *tex,
CoglTexture2D *
_cogl_texture_2d_gl_new_from_bitmap (CoglBitmap *bmp,
CoglPixelFormat internal_format,
+ CoglBool can_convert_in_place,
CoglError **error)
{
CoglContext *ctx = _cogl_bitmap_get_context (bmp);
CoglTexture2D *tex_2d;
- CoglBitmap *dst_bmp;
+ CoglBitmap *upload_bmp;
GLenum gl_intformat;
GLenum gl_format;
GLenum gl_type;
- dst_bmp = _cogl_texture_prepare_for_upload (bmp,
- internal_format,
- &internal_format,
- &gl_intformat,
- &gl_format,
- &gl_type,
- error);
- if (!dst_bmp)
+ upload_bmp = _cogl_bitmap_convert_for_upload (bmp,
+ internal_format,
+ can_convert_in_place,
+ error);
+ if (upload_bmp == NULL)
return NULL;
+ ctx->driver_vtable->pixel_format_to_gl (ctx,
+ cogl_bitmap_get_format (upload_bmp),
+ NULL, /* internal format */
+ &gl_format,
+ &gl_type);
+ ctx->driver_vtable->pixel_format_to_gl (ctx,
+ internal_format,
+ &gl_intformat,
+ NULL,
+ NULL);
+
tex_2d = _cogl_texture_2d_create_base (ctx,
cogl_bitmap_get_width (bmp),
cogl_bitmap_get_height (bmp),
@@ -180,10 +189,10 @@ _cogl_texture_2d_gl_new_from_bitmap (CoglBitmap *bmp,
if (!cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN))
{
CoglError *ignore = NULL;
- uint8_t *data = _cogl_bitmap_map (dst_bmp,
+ uint8_t *data = _cogl_bitmap_map (upload_bmp,
COGL_BUFFER_ACCESS_READ, 0,
&ignore);
- CoglPixelFormat format = cogl_bitmap_get_format (dst_bmp);
+ CoglPixelFormat format = cogl_bitmap_get_format (upload_bmp);
tex_2d->first_pixel.gl_format = gl_format;
tex_2d->first_pixel.gl_type = gl_type;
@@ -192,7 +201,7 @@ _cogl_texture_2d_gl_new_from_bitmap (CoglBitmap *bmp,
{
memcpy (tex_2d->first_pixel.data, data,
_cogl_pixel_format_get_bytes_per_pixel (format));
- _cogl_bitmap_unmap (dst_bmp);
+ _cogl_bitmap_unmap (upload_bmp);
}
else
{
@@ -210,25 +219,24 @@ _cogl_texture_2d_gl_new_from_bitmap (CoglBitmap *bmp,
GL_TEXTURE_2D,
tex_2d->gl_texture,
FALSE,
- dst_bmp,
+ upload_bmp,
gl_intformat,
gl_format,
gl_type,
error))
{
- cogl_object_unref (dst_bmp);
+ cogl_object_unref (upload_bmp);
cogl_object_unref (tex_2d);
return NULL;
}
tex_2d->gl_internal_format = gl_intformat;
- cogl_object_unref (dst_bmp);
+ cogl_object_unref (upload_bmp);
_cogl_texture_set_allocated (COGL_TEXTURE (tex_2d), TRUE);
return tex_2d;
-
}
#if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base)
@@ -555,29 +563,37 @@ _cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d,
{
CoglTexture *tex = COGL_TEXTURE (tex_2d);
CoglContext *ctx = tex->context;
+ CoglBitmap *upload_bmp;
+ CoglPixelFormat upload_format;
GLenum gl_format;
GLenum gl_type;
CoglBool status = TRUE;
- bmp = _cogl_texture_prepare_for_upload (bmp,
- cogl_texture_get_format (tex),
- NULL,
- NULL,
- &gl_format,
- &gl_type,
- error);
- if (!bmp)
+ upload_bmp =
+ _cogl_bitmap_convert_for_upload (bmp,
+ cogl_texture_get_format (tex),
+ FALSE, /* can't convert in place */
+ error);
+ if (upload_bmp == NULL)
return FALSE;
+ upload_format = cogl_bitmap_get_format (upload_bmp);
+
+ ctx->driver_vtable->pixel_format_to_gl (ctx,
+ upload_format,
+ NULL, /* internal format */
+ &gl_format,
+ &gl_type);
+
/* If this touches the first pixel then we'll update our copy */
if (dst_x == 0 && dst_y == 0 &&
!cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN))
{
CoglError *ignore = NULL;
uint8_t *data =
- _cogl_bitmap_map (bmp, COGL_BUFFER_ACCESS_READ, 0, &ignore);
+ _cogl_bitmap_map (upload_bmp, COGL_BUFFER_ACCESS_READ, 0, &ignore);
CoglPixelFormat bpp =
- _cogl_pixel_format_get_bytes_per_pixel (cogl_bitmap_get_format (bmp));
+ _cogl_pixel_format_get_bytes_per_pixel (upload_format);
tex_2d->first_pixel.gl_format = gl_format;
tex_2d->first_pixel.gl_type = gl_type;
@@ -585,7 +601,9 @@ _cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d,
if (data)
{
memcpy (tex_2d->first_pixel.data,
- data + cogl_bitmap_get_rowstride (bmp) * src_y + bpp * src_x,
+ (data +
+ cogl_bitmap_get_rowstride (upload_bmp) * src_y +
+ bpp * src_x),
bpp);
_cogl_bitmap_unmap (bmp);
}
@@ -605,12 +623,12 @@ _cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d,
dst_x, dst_y,
width, height,
level,
- bmp,
+ upload_bmp,
gl_format,
gl_type,
error);
- cogl_object_unref (bmp);
+ cogl_object_unref (upload_bmp);
_cogl_texture_gl_maybe_update_max_level (tex, level);
diff --git a/cogl/driver/nop/cogl-texture-2d-nop-private.h b/cogl/driver/nop/cogl-texture-2d-nop-private.h
index 1aa558a..f822a7f 100644
--- a/cogl/driver/nop/cogl-texture-2d-nop-private.h
+++ b/cogl/driver/nop/cogl-texture-2d-nop-private.h
@@ -51,6 +51,7 @@ _cogl_texture_2d_nop_allocate (CoglTexture *tex,
CoglTexture2D *
_cogl_texture_2d_nop_new_from_bitmap (CoglBitmap *bmp,
CoglPixelFormat internal_format,
+ CoglBool can_convert_in_place,
CoglError **error);
#if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base)
diff --git a/cogl/driver/nop/cogl-texture-2d-nop.c b/cogl/driver/nop/cogl-texture-2d-nop.c
index 5831e27..b63a7b7 100644
--- a/cogl/driver/nop/cogl-texture-2d-nop.c
+++ b/cogl/driver/nop/cogl-texture-2d-nop.c
@@ -65,6 +65,7 @@ _cogl_texture_2d_nop_allocate (CoglTexture *tex,
CoglTexture2D *
_cogl_texture_2d_nop_new_from_bitmap (CoglBitmap *bmp,
CoglPixelFormat internal_format,
+ CoglBool can_convert_in_place,
CoglError **error)
{
return _cogl_texture_2d_create_base (_cogl_bitmap_get_context (bmp),
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]