diff --git a/cogl/cogl-atlas-texture.c b/cogl/cogl-atlas-texture.c index 975b1995a..4542cb300 100644 --- a/cogl/cogl-atlas-texture.c +++ b/cogl/cogl-atlas-texture.c @@ -384,7 +384,6 @@ _cogl_atlas_texture_migrate_out_of_atlas (CoglAtlasTexture *atlas_tex) atlas_tex->rectangle.y + 1, atlas_tex->rectangle.width - 2, atlas_tex->rectangle.height - 2, - COGL_TEXTURE_NO_ATLAS, atlas_tex->format); /* Note: we simply silently ignore failures to migrate a texture * out (most likely due to lack of memory) and hope for the diff --git a/cogl/cogl-atlas.c b/cogl/cogl-atlas.c index d6c0e74f1..23f430b91 100644 --- a/cogl/cogl-atlas.c +++ b/cogl/cogl-atlas.c @@ -33,6 +33,7 @@ #include "cogl-context-private.h" #include "cogl-texture-private.h" #include "cogl-texture-2d-private.h" +#include "cogl-texture-2d-sliced.h" #include "cogl-texture-driver.h" #include "cogl-pipeline-opengl-private.h" #include "cogl-debug.h" @@ -541,13 +542,58 @@ _cogl_atlas_remove (CoglAtlas *atlas, _cogl_rectangle_map_get_height (atlas->map))); }; +static CoglTexture * +create_migration_texture (CoglContext *ctx, + int width, + int height, + CoglPixelFormat internal_format) +{ + CoglTexture *tex; + CoglError *skip_error = NULL; + + if ((_cogl_util_is_pot (width) && _cogl_util_is_pot (height)) || + (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_BASIC) && + cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP))) + { + /* First try creating a fast-path non-sliced texture */ + tex = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx, + width, height, + internal_format)); + + /* TODO: instead of allocating storage here it would be better + * if we had some api that let us just check that the size is + * supported by the hardware so storage could be allocated + * lazily when uploading data. */ + if (!cogl_texture_allocate (tex, &skip_error)) + { + cogl_error_free (skip_error); + cogl_object_unref (tex); + tex = NULL; + } + } + else + tex = NULL; + + if (!tex) + { + CoglTexture2DSliced *tex_2ds = + cogl_texture_2d_sliced_new_with_size (ctx, + width, + height, + COGL_TEXTURE_MAX_WASTE, + internal_format); + tex = COGL_TEXTURE (tex_2ds); + } + + return tex; +} + CoglTexture * _cogl_atlas_copy_rectangle (CoglAtlas *atlas, int x, int y, int width, int height, - CoglTextureFlags flags, CoglPixelFormat format) { CoglTexture *tex; @@ -557,7 +603,7 @@ _cogl_atlas_copy_rectangle (CoglAtlas *atlas, _COGL_GET_CONTEXT (ctx, NULL); /* Create a new texture at the right size */ - tex = cogl_texture_new_with_size (width, height, flags, format); + tex = create_migration_texture (ctx, width, height, format); if (!cogl_texture_allocate (tex, &ignore_error)) { cogl_error_free (ignore_error); diff --git a/cogl/cogl-atlas.h b/cogl/cogl-atlas.h index 85e0aab51..52530a905 100644 --- a/cogl/cogl-atlas.h +++ b/cogl/cogl-atlas.h @@ -80,7 +80,6 @@ _cogl_atlas_copy_rectangle (CoglAtlas *atlas, int y, int width, int height, - CoglTextureFlags flags, CoglPixelFormat format); void diff --git a/cogl/winsys/cogl-texture-pixmap-x11.c b/cogl/winsys/cogl-texture-pixmap-x11.c index 71d00ea95..18f73737d 100644 --- a/cogl/winsys/cogl-texture-pixmap-x11.c +++ b/cogl/winsys/cogl-texture-pixmap-x11.c @@ -38,6 +38,7 @@ #include "cogl-texture-private.h" #include "cogl-texture-driver.h" #include "cogl-texture-2d-private.h" +#include "cogl-texture-2d-sliced.h" #include "cogl-texture-rectangle-private.h" #include "cogl-context-private.h" #include "cogl-display-private.h" @@ -489,6 +490,52 @@ cogl_texture_pixmap_x11_set_damage_object (CoglTexturePixmapX11 *tex_pixmap, set_damage_object_internal (ctxt, tex_pixmap, damage, report_level); } +static CoglTexture * +create_fallback_texture (CoglContext *ctx, + int width, + int height, + CoglPixelFormat internal_format) +{ + CoglTexture *tex; + CoglError *skip_error = NULL; + + if ((_cogl_util_is_pot (width) && _cogl_util_is_pot (height)) || + (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_BASIC) && + cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP))) + { + /* First try creating a fast-path non-sliced texture */ + tex = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx, + width, height, + internal_format)); + + /* TODO: instead of allocating storage here it would be better + * if we had some api that let us just check that the size is + * supported by the hardware so storage could be allocated + * lazily when uploading data. */ + if (!cogl_texture_allocate (tex, &skip_error)) + { + cogl_error_free (skip_error); + cogl_object_unref (tex); + tex = NULL; + } + } + else + tex = NULL; + + if (!tex) + { + CoglTexture2DSliced *tex_2ds = + cogl_texture_2d_sliced_new_with_size (ctx, + width, + height, + COGL_TEXTURE_MAX_WASTE, + internal_format); + tex = COGL_TEXTURE (tex_2ds); + } + + return tex; +} + static void _cogl_texture_pixmap_x11_update_image_texture (CoglTexturePixmapX11 *tex_pixmap) { @@ -528,10 +575,10 @@ _cogl_texture_pixmap_x11_update_image_texture (CoglTexturePixmapX11 *tex_pixmap) ? COGL_PIXEL_FORMAT_RGBA_8888_PRE : COGL_PIXEL_FORMAT_RGB_888); - tex_pixmap->tex = cogl_texture_new_with_size (tex->width, - tex->height, - COGL_TEXTURE_NONE, - texture_format); + tex_pixmap->tex = create_fallback_texture (ctx, + tex->width, + tex->height, + texture_format); } if (tex_pixmap->image == NULL)