Allow npot Texture2D creation with only basic npot support

Cogl has feature flags for basic npot texture support and then separate
flags for npot + repeat and npot + mipmap. If those three features are
available then there is a feature for full-npot support too for
convenience. The cogl_texture_2d_new_ constructors were checking for
full npot support and failing if not available but since we expose the
fine grained features to the user the user should be able to check the
limitations of npot textures and still choose to allocate them.

_cogl_texture_2d_can_create() now only checks for basic npot support
when creating a npot texture.  Since this change also affects the
automagic cogl_texture_ constructors they now check for basic npot +
mipmap support before considering using a Texture2D.

Notably the cogl_texture_ constructors will try constructing a Texture2D
even if we don't have npot + repeat support since the alternative is a
sliced texture which will need manual repeating anyway. Accordingly the
Texture2D::can_hardware_repeat and ::transform_quad_coords_to_gl vfuncs
have been made aware of the npot + repeat feature flag.

Reviewed-by: Neil Roberts <neil@linux.intel.com>

(cherry picked from commit 6f6c5734d076372d98d0ec331b177ef7d65aa67d)
This commit is contained in:
Robert Bragg 2012-04-24 17:44:38 +01:00
parent b6b9ac0b85
commit 9cf7aac80f
4 changed files with 85 additions and 50 deletions

View File

@ -32,6 +32,33 @@
#include "cogl-buffer.h" #include "cogl-buffer.h"
#include "cogl-bitmap.h" #include "cogl-bitmap.h"
struct _CoglBitmap
{
CoglObject _parent;
/* Pointer back to the context that this bitmap was created with */
CoglContext *context;
CoglPixelFormat format;
int width;
int height;
int rowstride;
uint8_t *data;
CoglBool mapped;
CoglBool bound;
/* If this is non-null then 'data' is ignored and instead it is
fetched from this shared bitmap. */
CoglBitmap *shared_bmp;
/* If this is non-null then 'data' is treated as an offset into the
buffer and map will divert to mapping the buffer */
CoglBuffer *buffer;
};
/* /*
* _cogl_bitmap_new_with_malloc_buffer: * _cogl_bitmap_new_with_malloc_buffer:
* @context: A #CoglContext * @context: A #CoglContext

View File

@ -35,32 +35,6 @@
#include <string.h> #include <string.h>
struct _CoglBitmap
{
CoglObject _parent;
/* Pointer back to the context that this bitmap was created with */
CoglContext *context;
CoglPixelFormat format;
int width;
int height;
int rowstride;
uint8_t *data;
CoglBool mapped;
CoglBool bound;
/* If this is non-null then 'data' is ignored and instead it is
fetched from this shared bitmap. */
CoglBitmap *shared_bmp;
/* If this is non-null then 'data' is treated as an offset into the
buffer and map will divert to mapping the buffer */
CoglBuffer *buffer;
};
static void _cogl_bitmap_free (CoglBitmap *bmp); static void _cogl_bitmap_free (CoglBitmap *bmp);
COGL_OBJECT_DEFINE (Bitmap, bitmap); COGL_OBJECT_DEFINE (Bitmap, bitmap);

View File

@ -115,7 +115,7 @@ _cogl_texture_2d_can_create (unsigned int width,
/* If NPOT textures aren't supported then the size must be a power /* If NPOT textures aren't supported then the size must be a power
of two */ of two */
if (!cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT) && if (!cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_BASIC) &&
(!_cogl_util_is_pot (width) || (!_cogl_util_is_pot (width) ||
!_cogl_util_is_pot (height))) !_cogl_util_is_pot (height)))
return FALSE; return FALSE;
@ -631,7 +631,16 @@ _cogl_texture_2d_is_sliced (CoglTexture *tex)
static CoglBool static CoglBool
_cogl_texture_2d_can_hardware_repeat (CoglTexture *tex) _cogl_texture_2d_can_hardware_repeat (CoglTexture *tex)
{ {
return TRUE; CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex);
_COGL_GET_CONTEXT (ctx, FALSE);
if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT) ||
(_cogl_util_is_pot (tex_2d->width) &&
_cogl_util_is_pot (tex_2d->height)))
return TRUE;
else
return FALSE;
} }
static void static void
@ -650,15 +659,19 @@ _cogl_texture_2d_transform_quad_coords_to_gl (CoglTexture *tex,
/* The texture coordinates map directly so we don't need to do /* The texture coordinates map directly so we don't need to do
anything other than check for repeats */ anything other than check for repeats */
CoglBool need_repeat = FALSE;
int i; int i;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
if (coords[i] < 0.0f || coords[i] > 1.0f) if (coords[i] < 0.0f || coords[i] > 1.0f)
need_repeat = TRUE; {
/* Repeat is needed */
return (_cogl_texture_2d_can_hardware_repeat (tex) ?
COGL_TRANSFORM_HARDWARE_REPEAT :
COGL_TRANSFORM_SOFTWARE_REPEAT);
}
return (need_repeat ? COGL_TRANSFORM_HARDWARE_REPEAT /* No repeat is needed */
: COGL_TRANSFORM_NO_REPEAT); return COGL_TRANSFORM_NO_REPEAT;
} }
static CoglBool static CoglBool

View File

@ -322,11 +322,18 @@ cogl_texture_new_with_size (unsigned int width,
_COGL_GET_CONTEXT (ctx, NULL); _COGL_GET_CONTEXT (ctx, NULL);
/* First try creating a fast-path non-sliced texture */ if ((_cogl_util_is_pot (width) && _cogl_util_is_pot (height)) ||
tex = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx, (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_BASIC) &&
width, height, cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP)))
internal_format, {
NULL)); /* First try creating a fast-path non-sliced texture */
tex = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx,
width, height,
internal_format,
NULL));
}
else
tex = NULL;
if (tex) if (tex)
{ {
@ -393,7 +400,9 @@ cogl_texture_new_from_bitmap (CoglBitmap *bitmap,
CoglPixelFormat internal_format) CoglPixelFormat internal_format)
{ {
CoglAtlasTexture *atlas_tex; CoglAtlasTexture *atlas_tex;
CoglTexture2D *tex_2d; CoglTexture *tex;
_COGL_GET_CONTEXT (ctx, FALSE);
/* First try putting the texture in the atlas */ /* First try putting the texture in the atlas */
if ((atlas_tex = _cogl_atlas_texture_new_from_bitmap (bitmap, if ((atlas_tex = _cogl_atlas_texture_new_from_bitmap (bitmap,
@ -402,21 +411,33 @@ cogl_texture_new_from_bitmap (CoglBitmap *bitmap,
return COGL_TEXTURE (atlas_tex); return COGL_TEXTURE (atlas_tex);
/* If that doesn't work try a fast path 2D texture */ /* If that doesn't work try a fast path 2D texture */
if ((tex_2d = cogl_texture_2d_new_from_bitmap (bitmap, if ((_cogl_util_is_pot (bitmap->width) &&
internal_format, _cogl_util_is_pot (bitmap->height)) ||
NULL))) (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_BASIC) &&
cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP)))
{ {
cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (tex_2d), tex = COGL_TEXTURE (cogl_texture_2d_new_from_bitmap (bitmap,
!(flags & internal_format,
COGL_TEXTURE_NO_AUTO_MIPMAP)); NULL));
return COGL_TEXTURE (tex_2d); }
else
tex = NULL;
if (tex)
{
CoglBool auto_mipmap = !(flags & COGL_TEXTURE_NO_AUTO_MIPMAP);
cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (tex),
auto_mipmap);
}
else
{
/* Otherwise create a sliced texture */
tex = COGL_TEXTURE (_cogl_texture_2d_sliced_new_from_bitmap (bitmap,
flags,
internal_format));
} }
/* Otherwise create a sliced texture */ return tex;
return
COGL_TEXTURE (_cogl_texture_2d_sliced_new_from_bitmap (bitmap,
flags,
internal_format));
} }
CoglTexture * CoglTexture *