Expose CoglAtlasTexture api

This exposes the CoglAtlasTexture api, making the following public:
cogl_atlas_texture_new_with_size
cogl_atlas_texture_new_from_file
cogl_atlas_texture_new_from_data
cogl_atlas_texture_new_from_bitmap

The plan is to remove auto-texture apis like cogl_texture_new_from_file
since they are a bit too magic, but that means we need an explicit way
for users to allocate texture that will go in the atlas.

Although the _new_from_file() api is arguably redundant since you can
use _bitmap_new_from_file() followed by _atlas_texture_new_from_bitmap()
we don't want to loose any of the convenience that
cogl_texture_new_from_file() had.

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

(cherry picked from commit fe515e6063ba4c3ddb5cd00d2c8527d9a6336a12)

Conflicts:
	cogl/Makefile.am
This commit is contained in:
Robert Bragg 2013-06-08 01:58:05 +01:00 committed by Neil Roberts
parent 6f480c7530
commit fc5d1a8a68
8 changed files with 326 additions and 70 deletions

View File

@ -224,12 +224,11 @@ cogl_pango_glyph_cache_add_to_global_atlas (CoglPangoGlyphCache *cache,
if (cache->use_mipmapping) if (cache->use_mipmapping)
return FALSE; return FALSE;
texture = _cogl_atlas_texture_new_with_size (cache->ctx, texture = cogl_atlas_texture_new_with_size (cache->ctx,
value->draw_width, value->draw_width,
value->draw_height, value->draw_height,
COGL_TEXTURE_NONE, COGL_PIXEL_FORMAT_RGBA_8888_PRE,
COGL_PIXEL_FORMAT_RGBA_8888_PRE, &ignore_error);
&ignore_error);
if (texture == NULL) if (texture == NULL)
{ {

View File

@ -125,6 +125,7 @@ cogl_experimental_h = \
$(srcdir)/cogl-texture-rectangle.h \ $(srcdir)/cogl-texture-rectangle.h \
$(srcdir)/cogl-texture-2d-sliced.h \ $(srcdir)/cogl-texture-2d-sliced.h \
$(srcdir)/cogl-sub-texture.h \ $(srcdir)/cogl-sub-texture.h \
$(srcdir)/cogl-atlas-texture.h \
$(srcdir)/cogl-meta-texture.h \ $(srcdir)/cogl-meta-texture.h \
$(srcdir)/cogl-primitive-texture.h \ $(srcdir)/cogl-primitive-texture.h \
$(srcdir)/cogl-depth-state.h \ $(srcdir)/cogl-depth-state.h \
@ -577,7 +578,7 @@ libcogl_la_LDFLAGS = \
-no-undefined \ -no-undefined \
-version-info @COGL_LT_CURRENT@:@COGL_LT_REVISION@:@COGL_LT_AGE@ \ -version-info @COGL_LT_CURRENT@:@COGL_LT_REVISION@:@COGL_LT_AGE@ \
-export-dynamic \ -export-dynamic \
-export-symbols-regex "^(cogl|_cogl_debug_flags|_cogl_atlas_new|_cogl_atlas_add_reorganize_callback|_cogl_atlas_reserve_space|_cogl_callback|_cogl_util_get_eye_planes_for_screen_poly|_cogl_atlas_texture_remove_reorganize_callback|_cogl_atlas_texture_add_reorganize_callback|_cogl_texture_foreach_sub_texture_in_region|_cogl_atlas_texture_new_with_size|_cogl_profile_trace_message|_cogl_context_get_default|test_|unit_test_).*" -export-symbols-regex "^(cogl|_cogl_debug_flags|_cogl_atlas_new|_cogl_atlas_add_reorganize_callback|_cogl_atlas_reserve_space|_cogl_callback|_cogl_util_get_eye_planes_for_screen_poly|_cogl_atlas_texture_remove_reorganize_callback|_cogl_atlas_texture_add_reorganize_callback|_cogl_texture_foreach_sub_texture_in_region|_cogl_profile_trace_message|_cogl_context_get_default|test_|unit_test_).*"
libcogl_la_SOURCES = $(cogl_sources_c) libcogl_la_SOURCES = $(cogl_sources_c)
nodist_libcogl_la_SOURCES = $(BUILT_SOURCES) nodist_libcogl_la_SOURCES = $(BUILT_SOURCES)

View File

@ -21,17 +21,14 @@
* *
*/ */
#ifndef __COGL_ATLAS_TEXTURE_H #ifndef _COGL_ATLAS_TEXTURE_PRIVATE_H_
#define __COGL_ATLAS_TEXTURE_H #define _COGL_ATLAS_TEXTURE_PRIVATE_H_
#include "cogl-object-private.h" #include "cogl-object-private.h"
#include "cogl-texture-private.h" #include "cogl-texture-private.h"
#include "cogl-rectangle-map.h" #include "cogl-rectangle-map.h"
#include "cogl-atlas.h" #include "cogl-atlas.h"
#include "cogl-atlas-texture.h"
#define COGL_ATLAS_TEXTURE(tex) ((CoglAtlasTexture *) tex)
typedef struct _CoglAtlasTexture CoglAtlasTexture;
struct _CoglAtlasTexture struct _CoglAtlasTexture
{ {
@ -59,19 +56,10 @@ struct _CoglAtlasTexture
CoglAtlasTexture * CoglAtlasTexture *
_cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp, _cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp,
CoglTextureFlags flags,
CoglPixelFormat internal_format, CoglPixelFormat internal_format,
CoglBool can_convert_in_place, CoglBool can_convert_in_place,
CoglError **error); CoglError **error);
CoglAtlasTexture *
_cogl_atlas_texture_new_with_size (CoglContext *ctx,
int width,
int height,
CoglTextureFlags flags,
CoglPixelFormat internal_format,
CoglError **error);
void void
_cogl_atlas_texture_add_reorganize_callback (CoglContext *ctx, _cogl_atlas_texture_add_reorganize_callback (CoglContext *ctx,
GHookFunc callback, GHookFunc callback,
@ -85,4 +73,4 @@ _cogl_atlas_texture_remove_reorganize_callback (CoglContext *ctx,
CoglBool CoglBool
_cogl_is_atlas_texture (void *object); _cogl_is_atlas_texture (void *object);
#endif /* __COGL_ATLAS_TEXTURE_H */ #endif /* _COGL_ATLAS_TEXTURE_PRIVATE_H_ */

View File

@ -647,42 +647,14 @@ _cogl_atlas_texture_can_use_format (CoglPixelFormat format)
} }
CoglAtlasTexture * CoglAtlasTexture *
_cogl_atlas_texture_new_with_size (CoglContext *ctx, cogl_atlas_texture_new_with_size (CoglContext *ctx,
int width, int width,
int height, int height,
CoglTextureFlags flags, CoglPixelFormat internal_format,
CoglPixelFormat internal_format, CoglError **error)
CoglError **error)
{ {
CoglAtlasTexture *atlas_tex; CoglAtlasTexture *atlas_tex;
/* Don't put textures in the atlas if the user has explicitly
requested to disable it */
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_ATLAS)))
{
_cogl_set_error (error,
COGL_SYSTEM_ERROR,
COGL_SYSTEM_ERROR_UNSUPPORTED,
"Atlasing disabled");
return NULL;
}
/* We can't put the texture in the atlas if there are any special
flags. This precludes textures with COGL_TEXTURE_NO_ATLAS and
COGL_TEXTURE_NO_SLICING from being atlased */
if (flags)
{
/* XXX: This is a bit of an odd error; if we make this api
* public then this should probably be dealt with at a higher
* level, in cogl-auto-texture.c:cogl_texture_new_with_size().
*/
_cogl_set_error (error,
COGL_SYSTEM_ERROR,
COGL_SYSTEM_ERROR_UNSUPPORTED,
"Usage constraints preclude atlasing texture");
return NULL;
}
/* We can't atlas zero-sized textures because it breaks the atlas /* We can't atlas zero-sized textures because it breaks the atlas
data structure */ data structure */
if (width < 1 || height < 1) if (width < 1 || height < 1)
@ -789,7 +761,6 @@ _cogl_atlas_texture_allocate (CoglTexture *tex,
CoglAtlasTexture * CoglAtlasTexture *
_cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp, _cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp,
CoglTextureFlags flags,
CoglPixelFormat internal_format, CoglPixelFormat internal_format,
CoglBool can_convert_in_place, CoglBool can_convert_in_place,
CoglError **error) CoglError **error)
@ -810,10 +781,10 @@ _cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp,
internal_format = _cogl_texture_determine_internal_format (bmp_format, internal_format = _cogl_texture_determine_internal_format (bmp_format,
internal_format); internal_format);
atlas_tex = _cogl_atlas_texture_new_with_size (ctx, atlas_tex = cogl_atlas_texture_new_with_size (ctx,
bmp_width, bmp_height, bmp_width, bmp_height,
flags, internal_format, internal_format,
error); error);
if (!atlas_tex) if (!atlas_tex)
return NULL; return NULL;
@ -856,6 +827,74 @@ _cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp,
return atlas_tex; return atlas_tex;
} }
CoglAtlasTexture *
cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp,
CoglPixelFormat internal_format,
CoglError **error)
{
return _cogl_atlas_texture_new_from_bitmap (bmp, internal_format,
FALSE, error);
}
CoglAtlasTexture *
cogl_atlas_texture_new_from_data (CoglContext *ctx,
int width,
int height,
CoglPixelFormat format,
CoglPixelFormat internal_format,
int rowstride,
const uint8_t *data,
CoglError **error)
{
CoglBitmap *bmp;
CoglAtlasTexture *atlas_tex;
_COGL_RETURN_VAL_IF_FAIL (format != COGL_PIXEL_FORMAT_ANY, NULL);
_COGL_RETURN_VAL_IF_FAIL (data != NULL, NULL);
/* Rowstride from width if not given */
if (rowstride == 0)
rowstride = width * _cogl_pixel_format_get_bytes_per_pixel (format);
/* Wrap the data into a bitmap */
bmp = cogl_bitmap_new_for_data (ctx,
width, height,
format,
rowstride,
(uint8_t *) data);
atlas_tex = cogl_atlas_texture_new_from_bitmap (bmp, internal_format, error);
cogl_object_unref (bmp);
return atlas_tex;
}
CoglAtlasTexture *
cogl_atlas_texture_new_from_file (CoglContext *ctx,
const char *filename,
CoglPixelFormat internal_format,
CoglError **error)
{
CoglBitmap *bmp;
CoglAtlasTexture *atlas_tex = NULL;
_COGL_RETURN_VAL_IF_FAIL (error == NULL || *error == NULL, NULL);
bmp = cogl_bitmap_new_from_file (filename, error);
if (bmp == NULL)
return NULL;
atlas_tex = _cogl_atlas_texture_new_from_bitmap (bmp,
internal_format,
TRUE, /* convert in-place */
error);
cogl_object_unref (bmp);
return atlas_tex;
}
void void
_cogl_atlas_texture_add_reorganize_callback (CoglContext *ctx, _cogl_atlas_texture_add_reorganize_callback (CoglContext *ctx,
GHookFunc callback, GHookFunc callback,

214
cogl/cogl-atlas-texture.h Normal file
View File

@ -0,0 +1,214 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2013 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*
*
*/
#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION)
#error "Only <cogl/cogl.h> can be included directly."
#endif
#ifndef _COGL_ATLAS_TEXTURE_H_
#define _COGL_ATLAS_TEXTURE_H_
#include <cogl/cogl-context.h>
COGL_BEGIN_DECLS
/**
* SECTION:cogl-atlas-texture
* @short_description: Functions for managing textures in Cogl's global
* set of texture atlases
*
* A texture atlas is a texture that contains many smaller images that
* an application is interested in. These are packed together as a way
* of optimizing drawing with those images by avoiding the costs of
* repeatedly telling the hardware to change what texture it should
* sample from. This can enable more geometry to be batched together
* into few draw calls.
*
* Each #CoglContext has an shared, pool of texture atlases that are
* are managed by Cogl.
*
* This api lets applications upload texture data into one of Cogl's
* shared texture atlases using a high-level #CoglAtlasTexture which
* represents a sub-region of one of these atlases.
*
* <note>A #CoglAtlasTexture is a high-level meta texture which has
* some limitations to be aware of. Please see the documentation for
* #CoglMetaTexture for more details.</note>
*/
typedef struct _CoglAtlasTexture CoglAtlasTexture;
#define COGL_ATLAS_TEXTURE(tex) ((CoglAtlasTexture *) tex)
/**
* cogl_atlas_texture_new_with_size:
* @ctx: A #CoglContext
* @width: The width of your atlased texture.
* @height: The height of your atlased texture.
* @internal_format: The format of the texture
*
* Creates a #CoglAtlasTexture with a given @width and @height. A
* #CoglAtlasTexture represents a sub-region within one of Cogl's
* shared texture atlases.
*
* The storage for the texture is not allocated before this function
* returns. You can call cogl_texture_allocate() to explicitly
* allocate the underlying storage or let Cogl automatically allocate
* storage lazily.
*
* <note>This call can fail if Cogl considers the given
* @internal_format incompatible with the format of its internal
* atlases.</note>
*
* <note>The returned #CoglAtlasTexture is a high-level meta-texture
* with some limitations. See the documentation for #CoglMetaTexture
* for more details.</note>
*
* Returns: A new #CoglAtlasTexture object with no storage allocated
* yet or %NULL on failure and @error will be updated.
* Since: 1.16
* Stability: unstable
*/
CoglAtlasTexture *
cogl_atlas_texture_new_with_size (CoglContext *ctx,
int width,
int height,
CoglPixelFormat internal_format,
CoglError **error);
/**
* cogl_atlas_texture_new_from_file:
* @ctx: A #CoglContext
* @filename: the file to load
* @internal_format: The format of the texture
*
* Creates a #CoglAtlasTexture from an image file. A #CoglAtlasTexture
* represents a sub-region within one of Cogl's shared texture
* atlases.
*
* <note>This call can fail if Cogl considers the given
* @internal_format incompatible with the format of its internal
* atlases.</note>
*
* <note>The returned #CoglAtlasTexture is a high-level meta-texture
* with some limitations. See the documentation for #CoglMetaTexture
* for more details.</note>
*
* Returns: A new #CoglAtlasTexture object or %NULL on failure and
* @error will be updated.
* Since: 1.16
* Stability: unstable
*/
CoglAtlasTexture *
cogl_atlas_texture_new_from_file (CoglContext *ctx,
const char *filename,
CoglPixelFormat internal_format,
CoglError **error);
/**
* cogl_atlas_texture_new_from_data:
* @ctx: A #CoglContext
* @width: width of texture in pixels
* @height: height of texture in pixels
* @format: the #CoglPixelFormat the buffer is stored in in RAM
* @internal_format: the #CoglPixelFormat to use for the GPU storage of the
* texture. If %COGL_PIXEL_FORMAT_ANY is given then a premultiplied
* format similar to the format of the source data will be used. The
* default blending equations of Cogl expect premultiplied color data;
* the main use of passing a non-premultiplied format here is if you
* have non-premultiplied source data and are going to adjust the blend
* mode (see cogl_material_set_blend()) or use the data for something
* other than straight blending.
* @rowstride: the memory offset in bytes between the start of each
* row in @data. A value of 0 will make Cogl automatically
* calculate @rowstride from @width and @format.
* @data: pointer to the memory region where the source buffer resides
* @error: A #CoglError to catch exceptional errors or %NULL
*
* Creates a new #CoglAtlasTexture texture based on data residing in
* memory. A #CoglAtlasTexture represents a sub-region within one of
* Cogl's shared texture atlases.
*
* <note>This call can fail if Cogl considers the given
* @internal_format incompatible with the format of its internal
* atlases.</note>
*
* <note>The returned #CoglAtlasTexture is a high-level
* meta-texture with some limitations. See the documentation for
* #CoglMetaTexture for more details.</note>
*
* Returns: A new #CoglAtlasTexture object or %NULL on failure and
* @error will be updated.
* Since: 1.16
* Stability: unstable
*/
CoglAtlasTexture *
cogl_atlas_texture_new_from_data (CoglContext *ctx,
int width,
int height,
CoglPixelFormat format,
CoglPixelFormat internal_format,
int rowstride,
const uint8_t *data,
CoglError **error);
/**
* cogl_atlas_texture_new_from_bitmap:
* @bitmap: A #CoglBitmap
* @internal_format: the #CoglPixelFormat to use for the GPU storage of the
* texture. If %COGL_PIXEL_FORMAT_ANY is given then a premultiplied
* format similar to the format of the source data will be used. The
* default blending equations of Cogl expect premultiplied color data;
* the main use of passing a non-premultiplied format here is if you
* have non-premultiplied source data and are going to adjust the blend
* mode (see cogl_material_set_blend()) or use the data for something
* other than straight blending.
* @error: A #CoglError to catch exceptional errors or %NULL
*
* Creates a new #CoglAtlasTexture texture based on data residing in a
* @bitmap. A #CoglAtlasTexture represents a sub-region within one of
* Cogl's shared texture atlases.
*
* <note>This call can fail if Cogl considers the given
* @internal_format incompatible with the format of its internal
* atlases.</note>
*
* <note>The returned #CoglAtlasTexture is a high-level meta-texture
* with some limitations. See the documentation for #CoglMetaTexture
* for more details.</note>
*
* Returns: A new #CoglAtlasTexture object or %NULL on failure and
* @error will be updated.
* Since: 1.16
* Stability: unstable
*/
CoglAtlasTexture *
cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp,
CoglPixelFormat internal_format,
CoglError **error);
COGL_END_DECLS
#endif /* _COGL_ATLAS_TEXTURE_H_ */

View File

@ -185,16 +185,19 @@ _cogl_texture_new_from_bitmap (CoglBitmap *bitmap,
CoglTexture *tex; CoglTexture *tex;
CoglError *internal_error = NULL; CoglError *internal_error = NULL;
/* First try putting the texture in the atlas */ if (!flags &&
if ((atlas_tex = _cogl_atlas_texture_new_from_bitmap (bitmap, !COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_ATLAS))
flags, {
internal_format, /* First try putting the texture in the atlas */
can_convert_in_place, if ((atlas_tex = _cogl_atlas_texture_new_from_bitmap (bitmap,
&internal_error))) internal_format,
return COGL_TEXTURE (atlas_tex); can_convert_in_place,
&internal_error)))
return COGL_TEXTURE (atlas_tex);
cogl_error_free (internal_error); cogl_error_free (internal_error);
internal_error = NULL; internal_error = NULL;
}
/* If that doesn't work try a fast path 2D texture */ /* If that doesn't work try a fast path 2D texture */
if ((_cogl_util_is_pot (bitmap->width) && if ((_cogl_util_is_pot (bitmap->width) &&

View File

@ -93,6 +93,7 @@
#include <cogl/cogl-texture-3d.h> #include <cogl/cogl-texture-3d.h>
#include <cogl/cogl-texture-2d-sliced.h> #include <cogl/cogl-texture-2d-sliced.h>
#include <cogl/cogl-sub-texture.h> #include <cogl/cogl-sub-texture.h>
#include <cogl/cogl-atlas-texture.h>
#include <cogl/cogl-meta-texture.h> #include <cogl/cogl-meta-texture.h>
#include <cogl/cogl-primitive-texture.h> #include <cogl/cogl-primitive-texture.h>
#include <cogl/cogl-index-buffer.h> #include <cogl/cogl-index-buffer.h>

View File

@ -466,6 +466,17 @@ cogl_sub_texture_new
cogl_is_sub_texture cogl_is_sub_texture
</SECTION> </SECTION>
<SECTION>
<FILE>cogl-atlas-texture</FILE>
<TITLE>Atlas Textures</TITLE>
CoglAtlasTexture
cogl_atlas_texture_new_with_size
cogl_atlas_texture_new_from_file
cogl_atlas_texture_new_from_data
cogl_atlas_texture_new_from_bitmap
cogl_is_atlas_texture
</SECTION>
<SECTION> <SECTION>
<FILE>cogl-texture-2d-sliced</FILE> <FILE>cogl-texture-2d-sliced</FILE>
<TITLE>Sliced Textures</TITLE> <TITLE>Sliced Textures</TITLE>