{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
- cogl_atlas_remove_rectangle (ctx->atlas, &atlas_tex->rectangle);
+ _cogl_atlas_remove_rectangle (ctx->atlas, &atlas_tex->rectangle);
COGL_NOTE (ATLAS, "Removed rectangle sized %ix%i",
atlas_tex->rectangle.width,
atlas_tex->rectangle.height);
COGL_NOTE (ATLAS, "Atlas is %ix%i, has %i textures and is %i%% waste",
- cogl_atlas_get_width (ctx->atlas),
- cogl_atlas_get_height (ctx->atlas),
- cogl_atlas_get_n_rectangles (ctx->atlas),
- cogl_atlas_get_remaining_space (ctx->atlas) * 100 /
- (cogl_atlas_get_width (ctx->atlas) *
- cogl_atlas_get_height (ctx->atlas)));
+ _cogl_atlas_get_width (ctx->atlas),
+ _cogl_atlas_get_height (ctx->atlas),
+ _cogl_atlas_get_n_rectangles (ctx->atlas),
+ _cogl_atlas_get_remaining_space (ctx->atlas) * 100 /
+ (_cogl_atlas_get_width (ctx->atlas) *
+ _cogl_atlas_get_height (ctx->atlas)));
atlas_tex->in_atlas = FALSE;
}
the textures */
while (atlas_width < max_texture_size && atlas_height < max_texture_size)
{
- CoglAtlas *new_atlas = cogl_atlas_new (atlas_width, atlas_height, NULL);
+ CoglAtlas *new_atlas = _cogl_atlas_new (atlas_width, atlas_height, NULL);
guint i;
/* Add all of the textures and keep track of the new position */
for (i = 0; i < n_textures; i++)
- if (!cogl_atlas_add_rectangle (new_atlas,
- textures[i].texture->rectangle.width,
- textures[i].texture->rectangle.height,
- textures[i].texture,
- &textures[i].new_position))
+ if (!_cogl_atlas_add_rectangle (new_atlas,
+ textures[i].texture->rectangle.width,
+ textures[i].texture->rectangle.height,
+ textures[i].texture,
+ &textures[i].new_position))
break;
/* If the atlas can contain all of the textures then we have a
if (i >= n_textures)
return new_atlas;
- cogl_atlas_free (new_atlas);
+ _cogl_atlas_free (new_atlas);
_cogl_atlas_texture_get_next_size (&atlas_width, &atlas_height);
}
_COGL_GET_CONTEXT (ctx, FALSE);
/* Check if we can fit the rectangle into the existing atlas */
- if (ctx->atlas && cogl_atlas_add_rectangle (ctx->atlas, width, height,
+ if (ctx->atlas && _cogl_atlas_add_rectangle (ctx->atlas, width, height,
new_sub_tex,
&new_sub_tex->rectangle))
{
COGL_NOTE (ATLAS, "Atlas is %ix%i, has %i textures and is %i%% waste",
- cogl_atlas_get_width (ctx->atlas),
- cogl_atlas_get_height (ctx->atlas),
- cogl_atlas_get_n_rectangles (ctx->atlas),
- cogl_atlas_get_remaining_space (ctx->atlas) * 100 /
- (cogl_atlas_get_width (ctx->atlas) *
- cogl_atlas_get_height (ctx->atlas)));
+ _cogl_atlas_get_width (ctx->atlas),
+ _cogl_atlas_get_height (ctx->atlas),
+ _cogl_atlas_get_n_rectangles (ctx->atlas),
+ _cogl_atlas_get_remaining_space (ctx->atlas) * 100 /
+ (_cogl_atlas_get_width (ctx->atlas) *
+ _cogl_atlas_get_height (ctx->atlas)));
return TRUE;
}
data.textures = g_malloc (sizeof (CoglAtlasTextureRepositionData));
else
{
- data.textures = g_malloc (sizeof (CoglAtlasTextureRepositionData) *
- (cogl_atlas_get_n_rectangles (ctx->atlas) + 1));
- cogl_atlas_foreach (ctx->atlas, _cogl_atlas_texture_get_rectangles_cb,
- &data);
+ data.textures =
+ g_malloc (sizeof (CoglAtlasTextureRepositionData) *
+ (_cogl_atlas_get_n_rectangles (ctx->atlas) + 1));
+ _cogl_atlas_foreach (ctx->atlas, _cogl_atlas_texture_get_rectangles_cb,
+ &data);
}
/* Add the new rectangle as a dummy texture so that it can be
/* Try to create a new atlas that can contain all of the textures */
if (ctx->atlas)
{
- atlas_width = cogl_atlas_get_width (ctx->atlas);
- atlas_height = cogl_atlas_get_height (ctx->atlas);
+ atlas_width = _cogl_atlas_get_width (ctx->atlas);
+ atlas_height = _cogl_atlas_get_height (ctx->atlas);
/* If there is enough space in the existing for the new
rectangle in the existing atlas we'll start with the same
size, otherwise we'll immediately double it */
- if (cogl_atlas_get_remaining_space (ctx->atlas) < width * height)
+ if (_cogl_atlas_get_remaining_space (ctx->atlas) < width * height)
_cogl_atlas_texture_get_next_size (&atlas_width, &atlas_height);
}
else
{
/* We need to migrate the existing textures into a new texture */
new_tex =
- _cogl_texture_2d_new_with_size (cogl_atlas_get_width (new_atlas),
- cogl_atlas_get_height (new_atlas),
+ _cogl_texture_2d_new_with_size (_cogl_atlas_get_width (new_atlas),
+ _cogl_atlas_get_height (new_atlas),
COGL_TEXTURE_NONE,
COGL_PIXEL_FORMAT_RGBA_8888);
COGL_NOTE (ATLAS,
"Atlas %s with size %ix%i",
ctx->atlas == NULL ||
- cogl_atlas_get_width (ctx->atlas) !=
- cogl_atlas_get_width (new_atlas) ||
- cogl_atlas_get_height (ctx->atlas) !=
- cogl_atlas_get_height (new_atlas) ?
+ _cogl_atlas_get_width (ctx->atlas) !=
+ _cogl_atlas_get_width (new_atlas) ||
+ _cogl_atlas_get_height (ctx->atlas) !=
+ _cogl_atlas_get_height (new_atlas) ?
"resized" : "reorganized",
- cogl_atlas_get_width (new_atlas),
- cogl_atlas_get_height (new_atlas));
+ _cogl_atlas_get_width (new_atlas),
+ _cogl_atlas_get_height (new_atlas));
if (ctx->atlas)
{
ctx->atlas_texture,
new_tex,
new_sub_tex);
- cogl_atlas_free (ctx->atlas);
+ _cogl_atlas_free (ctx->atlas);
cogl_handle_unref (ctx->atlas_texture);
}
else
ctx->atlas_texture = new_tex;
COGL_NOTE (ATLAS, "Atlas is %ix%i, has %i textures and is %i%% waste",
- cogl_atlas_get_width (ctx->atlas),
- cogl_atlas_get_height (ctx->atlas),
- cogl_atlas_get_n_rectangles (ctx->atlas),
- cogl_atlas_get_remaining_space (ctx->atlas) * 100 /
- (cogl_atlas_get_width (ctx->atlas) *
- cogl_atlas_get_height (ctx->atlas)));
+ _cogl_atlas_get_width (ctx->atlas),
+ _cogl_atlas_get_height (ctx->atlas),
+ _cogl_atlas_get_n_rectangles (ctx->atlas),
+ _cogl_atlas_get_remaining_space (ctx->atlas) * 100 /
+ (_cogl_atlas_get_width (ctx->atlas) *
+ _cogl_atlas_get_height (ctx->atlas)));
ret = TRUE;
}
&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);
return COGL_INVALID_HANDLE;
}
the atlas */
#include <cairo.h>
-static void cogl_atlas_dump_image (CoglAtlas *atlas);
+static void _cogl_atlas_dump_image (CoglAtlas *atlas);
#endif /* COGL_ENABLE_DEBUG */
};
static CoglAtlasNode *
-cogl_atlas_node_new (void)
+_cogl_atlas_node_new (void)
{
return g_slice_new (CoglAtlasNode);
}
static void
-cogl_atlas_node_free (CoglAtlasNode *node)
+_cogl_atlas_node_free (CoglAtlasNode *node)
{
g_slice_free (CoglAtlasNode, node);
}
CoglAtlas *
-cogl_atlas_new (guint width, guint height,
- GDestroyNotify value_destroy_func)
+_cogl_atlas_new (guint width, guint height,
+ GDestroyNotify value_destroy_func)
{
CoglAtlas *atlas = g_new (CoglAtlas, 1);
- CoglAtlasNode *root = cogl_atlas_node_new ();
+ CoglAtlasNode *root = _cogl_atlas_node_new ();
root->type = COGL_ATLAS_EMPTY_LEAF;
root->parent = NULL;
}
static CoglAtlasStackEntry *
-cogl_atlas_stack_push (CoglAtlasStackEntry *stack,
- CoglAtlasNode *node,
- gboolean next_index)
+_cogl_atlas_stack_push (CoglAtlasStackEntry *stack,
+ CoglAtlasNode *node,
+ gboolean next_index)
{
CoglAtlasStackEntry *new_entry = g_slice_new (CoglAtlasStackEntry);
}
static CoglAtlasStackEntry *
-cogl_atlas_stack_pop (CoglAtlasStackEntry *stack)
+_cogl_atlas_stack_pop (CoglAtlasStackEntry *stack)
{
CoglAtlasStackEntry *next = stack->next;
}
static CoglAtlasNode *
-cogl_atlas_node_split_horizontally (CoglAtlasNode *node,
- guint left_width)
+_cogl_atlas_node_split_horizontally (CoglAtlasNode *node,
+ guint left_width)
{
/* Splits the node horizontally (according to emacs' definition, not
vim) by converting it to a branch and adding two new leaf
if (node->rectangle.width == left_width)
return node;
- left_node = cogl_atlas_node_new ();
+ left_node = _cogl_atlas_node_new ();
left_node->type = COGL_ATLAS_EMPTY_LEAF;
left_node->parent = node;
left_node->rectangle.x = node->rectangle.x;
left_node->rectangle.height = node->rectangle.height;
node->d.branch.left = left_node;
- right_node = cogl_atlas_node_new ();
+ right_node = _cogl_atlas_node_new ();
right_node->type = COGL_ATLAS_EMPTY_LEAF;
right_node->parent = node;
right_node->rectangle.x = node->rectangle.x + left_width;
}
static CoglAtlasNode *
-cogl_atlas_node_split_vertically (CoglAtlasNode *node,
- guint top_height)
+_cogl_atlas_node_split_vertically (CoglAtlasNode *node,
+ guint top_height)
{
/* Splits the node vertically (according to emacs' definition, not
vim) by converting it to a branch and adding two new leaf
if (node->rectangle.height == top_height)
return node;
- top_node = cogl_atlas_node_new ();
+ top_node = _cogl_atlas_node_new ();
top_node->type = COGL_ATLAS_EMPTY_LEAF;
top_node->parent = node;
top_node->rectangle.x = node->rectangle.x;
top_node->rectangle.height = top_height;
node->d.branch.left = top_node;
- bottom_node = cogl_atlas_node_new ();
+ bottom_node = _cogl_atlas_node_new ();
bottom_node->type = COGL_ATLAS_EMPTY_LEAF;
bottom_node->parent = node;
bottom_node->rectangle.x = node->rectangle.x;
}
gboolean
-cogl_atlas_add_rectangle (CoglAtlas *atlas,
- guint width, guint height,
- gpointer data,
- CoglAtlasRectangle *rectangle)
+_cogl_atlas_add_rectangle (CoglAtlas *atlas,
+ guint width, guint height,
+ gpointer data,
+ CoglAtlasRectangle *rectangle)
{
/* Stack of nodes to search in */
CoglAtlasStackEntry *node_stack;
g_return_val_if_fail (width > 0 && height > 0, FALSE);
/* Start with the root node */
- node_stack = cogl_atlas_stack_push (NULL, atlas->root, FALSE);
+ node_stack = _cogl_atlas_stack_push (NULL, atlas->root, FALSE);
/* Depth-first search for an empty node that is big enough */
while (node_stack)
/* Pop an entry off the stack */
CoglAtlasNode *node = node_stack->node;
int next_index = node_stack->next_index;
- node_stack = cogl_atlas_stack_pop (node_stack);
+ node_stack = _cogl_atlas_stack_pop (node_stack);
/* Regardless of the type of the node, there's no point
descending any further if the new rectangle won't fit within
{
if (next_index)
/* Try the right branch */
- node_stack = cogl_atlas_stack_push (node_stack,
- node->d.branch.right,
- 0);
+ node_stack = _cogl_atlas_stack_push (node_stack,
+ node->d.branch.right,
+ 0);
else
{
/* Make sure we remember to try the right branch once
we've finished descending the left branch */
- node_stack = cogl_atlas_stack_push (node_stack,
- node,
- 1);
+ node_stack = _cogl_atlas_stack_push (node_stack,
+ node,
+ 1);
/* Try the left branch */
- node_stack = cogl_atlas_stack_push (node_stack,
- node->d.branch.left,
- 0);
+ node_stack = _cogl_atlas_stack_push (node_stack,
+ node->d.branch.left,
+ 0);
}
}
}
/* Free the stack */
while (node_stack)
- node_stack = cogl_atlas_stack_pop (node_stack);
+ node_stack = _cogl_atlas_stack_pop (node_stack);
if (found_node)
{
if (found_node->rectangle.width - width >
found_node->rectangle.height - height)
{
- found_node = cogl_atlas_node_split_horizontally (found_node, width);
- found_node = cogl_atlas_node_split_vertically (found_node, height);
+ found_node = _cogl_atlas_node_split_horizontally (found_node, width);
+ found_node = _cogl_atlas_node_split_vertically (found_node, height);
}
else
{
- found_node = cogl_atlas_node_split_vertically (found_node, height);
- found_node = cogl_atlas_node_split_horizontally (found_node, width);
+ found_node = _cogl_atlas_node_split_vertically (found_node, height);
+ found_node = _cogl_atlas_node_split_horizontally (found_node, width);
}
found_node->type = COGL_ATLAS_FILLED_LEAF;
#ifdef COGL_ENABLE_DEBUG
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_DUMP_ATLAS_IMAGE))
- cogl_atlas_dump_image (atlas);
+ _cogl_atlas_dump_image (atlas);
#endif
return TRUE;
}
void
-cogl_atlas_remove_rectangle (CoglAtlas *atlas,
- const CoglAtlasRectangle *rectangle)
+_cogl_atlas_remove_rectangle (CoglAtlas *atlas,
+ const CoglAtlasRectangle *rectangle)
{
CoglAtlasNode *node = atlas->root;
if (node->d.branch.left->type == COGL_ATLAS_EMPTY_LEAF &&
node->d.branch.right->type == COGL_ATLAS_EMPTY_LEAF)
{
- cogl_atlas_node_free (node->d.branch.left);
- cogl_atlas_node_free (node->d.branch.right);
+ _cogl_atlas_node_free (node->d.branch.left);
+ _cogl_atlas_node_free (node->d.branch.right);
node->type = COGL_ATLAS_EMPTY_LEAF;
}
else
#ifdef COGL_ENABLE_DEBUG
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_DUMP_ATLAS_IMAGE))
- cogl_atlas_dump_image (atlas);
+ _cogl_atlas_dump_image (atlas);
#endif
}
guint
-cogl_atlas_get_width (CoglAtlas *atlas)
+_cogl_atlas_get_width (CoglAtlas *atlas)
{
return atlas->root->rectangle.width;
}
guint
-cogl_atlas_get_height (CoglAtlas *atlas)
+_cogl_atlas_get_height (CoglAtlas *atlas)
{
return atlas->root->rectangle.height;
}
guint
-cogl_atlas_get_remaining_space (CoglAtlas *atlas)
+_cogl_atlas_get_remaining_space (CoglAtlas *atlas)
{
return atlas->space_remaining;
}
guint
-cogl_atlas_get_n_rectangles (CoglAtlas *atlas)
+_cogl_atlas_get_n_rectangles (CoglAtlas *atlas)
{
return atlas->n_rectangles;
}
static void
-cogl_atlas_internal_foreach (CoglAtlas *atlas,
- CoglAtlasInternalForeachCb callback,
- gpointer data)
+_cogl_atlas_internal_foreach (CoglAtlas *atlas,
+ CoglAtlasInternalForeachCb callback,
+ gpointer data)
{
/* Stack of nodes to search in */
CoglAtlasStackEntry *node_stack;
/* Start with the root node */
- node_stack = cogl_atlas_stack_push (NULL, atlas->root, 0);
+ node_stack = _cogl_atlas_stack_push (NULL, atlas->root, 0);
/* Iterate all nodes depth-first */
while (node_stack)
node_stack->next_index = 1;
/* Explore the left branch next */
- node_stack = cogl_atlas_stack_push (node_stack,
+ node_stack = _cogl_atlas_stack_push (node_stack,
node->d.branch.left,
0);
}
node_stack->next_index = 2;
/* Explore the right branch next */
- node_stack = cogl_atlas_stack_push (node_stack,
+ node_stack = _cogl_atlas_stack_push (node_stack,
node->d.branch.right,
0);
}
{
/* We're finished with this node so we can call the callback */
callback (node, data);
- node_stack = cogl_atlas_stack_pop (node_stack);
+ node_stack = _cogl_atlas_stack_pop (node_stack);
}
break;
default:
/* Some sort of leaf node, just call the callback */
callback (node, data);
- node_stack = cogl_atlas_stack_pop (node_stack);
+ node_stack = _cogl_atlas_stack_pop (node_stack);
break;
}
}
} CoglAtlasForeachClosure;
static void
-cogl_atlas_foreach_cb (CoglAtlasNode *node, gpointer data)
+_cogl_atlas_foreach_cb (CoglAtlasNode *node, gpointer data)
{
CoglAtlasForeachClosure *closure = data;
}
void
-cogl_atlas_foreach (CoglAtlas *atlas,
- CoglAtlasCallback callback,
- gpointer data)
+_cogl_atlas_foreach (CoglAtlas *atlas,
+ CoglAtlasCallback callback,
+ gpointer data)
{
CoglAtlasForeachClosure closure;
closure.callback = callback;
closure.data = data;
- cogl_atlas_internal_foreach (atlas, cogl_atlas_foreach_cb, &closure);
+ _cogl_atlas_internal_foreach (atlas, _cogl_atlas_foreach_cb, &closure);
}
static void
-cogl_atlas_free_cb (CoglAtlasNode *node, gpointer data)
+_cogl_atlas_free_cb (CoglAtlasNode *node, gpointer data)
{
CoglAtlas *atlas = data;
if (node->type == COGL_ATLAS_FILLED_LEAF && atlas->value_destroy_func)
atlas->value_destroy_func (node->d.data);
- cogl_atlas_node_free (node);
+ _cogl_atlas_node_free (node);
}
void
-cogl_atlas_free (CoglAtlas *atlas)
+_cogl_atlas_free (CoglAtlas *atlas)
{
- cogl_atlas_internal_foreach (atlas, cogl_atlas_free_cb, atlas);
+ _cogl_atlas_internal_foreach (atlas, _cogl_atlas_free_cb, atlas);
g_free (atlas);
}
#ifdef COGL_ENABLE_DEBUG
static void
-cogl_atlas_dump_image_cb (CoglAtlasNode *node, gpointer data)
+_cogl_atlas_dump_image_cb (CoglAtlasNode *node, gpointer data)
{
cairo_t *cr = data;
}
static void
-cogl_atlas_dump_image (CoglAtlas *atlas)
+_cogl_atlas_dump_image (CoglAtlas *atlas)
{
/* This dumps a png to help visualize the atlas. Each leaf rectangle
is drawn with a white outline. Unused leaves are filled in black
cairo_surface_t *surface =
cairo_image_surface_create (CAIRO_FORMAT_RGB24,
- cogl_atlas_get_width (atlas),
- cogl_atlas_get_height (atlas));
+ _cogl_atlas_get_width (atlas),
+ _cogl_atlas_get_height (atlas));
cairo_t *cr = cairo_create (surface);
- cogl_atlas_internal_foreach (atlas, cogl_atlas_dump_image_cb, cr);
+ _cogl_atlas_internal_foreach (atlas, _cogl_atlas_dump_image_cb, cr);
cairo_destroy (cr);