mirror of
https://github.com/brl/mutter.git
synced 2024-12-23 11:32:04 +00:00
Allow lazy texture storage allocation
Consistent with how we lazily allocate framebuffers this patch allows us to instantiate textures but still specify constraints and requirements before allocating storage so that we can be sure to allocate the most appropriate/efficient storage. This adds a cogl_texture_allocate() function that is analogous to cogl_framebuffer_allocate() which can optionally be called to explicitly allocate storage and catch any errors. If this function isn't used explicitly then Cogl will implicitly ensure textures are allocated before the storage is needed. It is generally recommended to rely on lazy storage allocation or at least perform explicit allocation as late as possible so Cogl can be fully informed about the best way to allocate storage. Reviewed-by: Neil Roberts <neil@linux.intel.com> (cherry picked from commit 1fa7c0f10a8a03043e3c75cb079a49625df098b7) Note: This reverts the cogl_texture_rectangle_new_with_size API change that dropped the CoglError argument and keeps the semantics of allocating the texture immediately. This is because Mutter currently uses this API so we will probably look at updating this later once we have a corresponding Mutter patch prepared. The other API changes were kept since they only affected experimental api.
This commit is contained in:
parent
5a814e386a
commit
73e8a6d7ce
@ -214,6 +214,7 @@ cogl_pango_glyph_cache_add_to_global_atlas (CoglPangoGlyphCache *cache,
|
|||||||
CoglPangoGlyphCacheValue *value)
|
CoglPangoGlyphCacheValue *value)
|
||||||
{
|
{
|
||||||
CoglAtlasTexture *texture;
|
CoglAtlasTexture *texture;
|
||||||
|
CoglError *ignore_error = NULL;
|
||||||
|
|
||||||
if (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_SHARED_ATLAS))
|
if (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_SHARED_ATLAS))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -227,10 +228,14 @@ cogl_pango_glyph_cache_add_to_global_atlas (CoglPangoGlyphCache *cache,
|
|||||||
value->draw_width,
|
value->draw_width,
|
||||||
value->draw_height,
|
value->draw_height,
|
||||||
COGL_TEXTURE_NONE,
|
COGL_TEXTURE_NONE,
|
||||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE);
|
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||||
|
&ignore_error);
|
||||||
|
|
||||||
if (texture == NULL)
|
if (texture == NULL)
|
||||||
return FALSE;
|
{
|
||||||
|
cogl_error_free (ignore_error);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
value->texture = COGL_TEXTURE (texture);
|
value->texture = COGL_TEXTURE (texture);
|
||||||
value->tx1 = 0;
|
value->tx1 = 0;
|
||||||
|
@ -68,7 +68,8 @@ _cogl_atlas_texture_new_with_size (CoglContext *ctx,
|
|||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
CoglTextureFlags flags,
|
CoglTextureFlags flags,
|
||||||
CoglPixelFormat internal_format);
|
CoglPixelFormat internal_format,
|
||||||
|
CoglError **error);
|
||||||
|
|
||||||
void
|
void
|
||||||
_cogl_atlas_texture_add_reorganize_callback (CoglContext *ctx,
|
_cogl_atlas_texture_add_reorganize_callback (CoglContext *ctx,
|
||||||
|
@ -651,32 +651,60 @@ _cogl_atlas_texture_new_with_size (CoglContext *ctx,
|
|||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
CoglTextureFlags flags,
|
CoglTextureFlags flags,
|
||||||
CoglPixelFormat internal_format)
|
CoglPixelFormat internal_format,
|
||||||
|
CoglError **error)
|
||||||
{
|
{
|
||||||
CoglAtlasTexture *atlas_tex;
|
CoglAtlasTexture *atlas_tex;
|
||||||
CoglAtlas *atlas;
|
|
||||||
GSList *l;
|
|
||||||
|
|
||||||
/* Don't put textures in the atlas if the user has explicitly
|
/* Don't put textures in the atlas if the user has explicitly
|
||||||
requested to disable it */
|
requested to disable it */
|
||||||
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_ATLAS)))
|
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_ATLAS)))
|
||||||
return NULL;
|
{
|
||||||
|
_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
|
/* We can't put the texture in the atlas if there are any special
|
||||||
flags. This precludes textures with COGL_TEXTURE_NO_ATLAS and
|
flags. This precludes textures with COGL_TEXTURE_NO_ATLAS and
|
||||||
COGL_TEXTURE_NO_SLICING from being atlased */
|
COGL_TEXTURE_NO_SLICING from being atlased */
|
||||||
if (flags)
|
if (flags)
|
||||||
return NULL;
|
{
|
||||||
|
/* 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)
|
||||||
return NULL;
|
{
|
||||||
|
_cogl_set_error (error,
|
||||||
|
COGL_TEXTURE_ERROR,
|
||||||
|
COGL_TEXTURE_ERROR_SIZE,
|
||||||
|
"1x1 atlas textures not supported");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* If we can't use FBOs then it will be too slow to migrate textures
|
/* If we can't use FBOs then it will be too slow to migrate textures
|
||||||
and we shouldn't use the atlas */
|
and we shouldn't use the atlas */
|
||||||
if (!cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN))
|
if (!cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN))
|
||||||
return NULL;
|
{
|
||||||
|
_cogl_set_error (error,
|
||||||
|
COGL_SYSTEM_ERROR,
|
||||||
|
COGL_SYSTEM_ERROR_UNSUPPORTED,
|
||||||
|
"Atlasing disabled because migrations "
|
||||||
|
"would be too slow");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
COGL_NOTE (ATLAS, "Adding texture of size %ix%i", width, height);
|
COGL_NOTE (ATLAS, "Adding texture of size %ix%i", width, height);
|
||||||
|
|
||||||
@ -685,7 +713,10 @@ _cogl_atlas_texture_new_with_size (CoglContext *ctx,
|
|||||||
{
|
{
|
||||||
COGL_NOTE (ATLAS, "Texture can not be added because the "
|
COGL_NOTE (ATLAS, "Texture can not be added because the "
|
||||||
"format is unsupported");
|
"format is unsupported");
|
||||||
|
_cogl_set_error (error,
|
||||||
|
COGL_TEXTURE_ERROR,
|
||||||
|
COGL_TEXTURE_ERROR_FORMAT,
|
||||||
|
"Texture format unsuitable for atlasing");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -703,12 +734,27 @@ _cogl_atlas_texture_new_with_size (CoglContext *ctx,
|
|||||||
|
|
||||||
atlas_tex->sub_texture = NULL;
|
atlas_tex->sub_texture = NULL;
|
||||||
|
|
||||||
|
atlas_tex->format = internal_format;
|
||||||
|
atlas_tex->atlas = NULL;
|
||||||
|
|
||||||
|
return _cogl_atlas_texture_object_new (atlas_tex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CoglBool
|
||||||
|
_cogl_atlas_texture_allocate (CoglTexture *tex,
|
||||||
|
CoglError **error)
|
||||||
|
{
|
||||||
|
CoglContext *ctx = tex->context;
|
||||||
|
CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex);
|
||||||
|
CoglAtlas *atlas;
|
||||||
|
GSList *l;
|
||||||
|
|
||||||
/* Look for an existing atlas that can hold the texture */
|
/* Look for an existing atlas that can hold the texture */
|
||||||
for (l = ctx->atlases; l; l = l->next)
|
for (l = ctx->atlases; l; l = l->next)
|
||||||
/* Try to make some space in the atlas for the texture */
|
/* Try to make some space in the atlas for the texture */
|
||||||
if (_cogl_atlas_reserve_space (atlas = l->data,
|
if (_cogl_atlas_reserve_space (atlas = l->data,
|
||||||
/* Add two pixels for the border */
|
/* Add two pixels for the border */
|
||||||
width + 2, height + 2,
|
tex->width + 2, tex->height + 2,
|
||||||
atlas_tex))
|
atlas_tex))
|
||||||
{
|
{
|
||||||
cogl_object_ref (atlas);
|
cogl_object_ref (atlas);
|
||||||
@ -722,20 +768,23 @@ _cogl_atlas_texture_new_with_size (CoglContext *ctx,
|
|||||||
COGL_NOTE (ATLAS, "Created new atlas for textures: %p", atlas);
|
COGL_NOTE (ATLAS, "Created new atlas for textures: %p", atlas);
|
||||||
if (!_cogl_atlas_reserve_space (atlas,
|
if (!_cogl_atlas_reserve_space (atlas,
|
||||||
/* Add two pixels for the border */
|
/* Add two pixels for the border */
|
||||||
width + 2, height + 2,
|
tex->width + 2, tex->height + 2,
|
||||||
atlas_tex))
|
atlas_tex))
|
||||||
{
|
{
|
||||||
/* Ok, this means we really can't add it to the atlas */
|
/* Ok, this means we really can't add it to the atlas */
|
||||||
cogl_object_unref (atlas);
|
cogl_object_unref (atlas);
|
||||||
g_free (atlas_tex);
|
|
||||||
return NULL;
|
_cogl_set_error (error,
|
||||||
|
COGL_SYSTEM_ERROR,
|
||||||
|
COGL_SYSTEM_ERROR_NO_MEMORY,
|
||||||
|
"Not enough memory to atlas texture");
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
atlas_tex->format = internal_format;
|
|
||||||
atlas_tex->atlas = atlas;
|
atlas_tex->atlas = atlas;
|
||||||
|
|
||||||
return _cogl_atlas_texture_object_new (atlas_tex);
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
CoglAtlasTexture *
|
CoglAtlasTexture *
|
||||||
@ -762,14 +811,14 @@ _cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp,
|
|||||||
|
|
||||||
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);
|
flags, internal_format,
|
||||||
|
error);
|
||||||
|
if (!atlas_tex)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (atlas_tex == NULL)
|
if (!cogl_texture_allocate (COGL_TEXTURE (atlas_tex), error))
|
||||||
{
|
{
|
||||||
_cogl_set_error (error,
|
cogl_object_unref (atlas_tex);
|
||||||
COGL_SYSTEM_ERROR,
|
|
||||||
COGL_SYSTEM_ERROR_UNSUPPORTED,
|
|
||||||
"Texture type not compatible with atlas");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -839,6 +888,7 @@ static const CoglTextureVtable
|
|||||||
cogl_atlas_texture_vtable =
|
cogl_atlas_texture_vtable =
|
||||||
{
|
{
|
||||||
FALSE, /* not primitive */
|
FALSE, /* not primitive */
|
||||||
|
_cogl_atlas_texture_allocate,
|
||||||
_cogl_atlas_texture_set_region,
|
_cogl_atlas_texture_set_region,
|
||||||
NULL, /* get_data */
|
NULL, /* get_data */
|
||||||
_cogl_atlas_texture_foreach_sub_texture_in_region,
|
_cogl_atlas_texture_foreach_sub_texture_in_region,
|
||||||
|
@ -301,6 +301,9 @@ _cogl_atlas_create_texture (CoglAtlas *atlas,
|
|||||||
tex = cogl_texture_2d_new_from_bitmap (clear_bmp,
|
tex = cogl_texture_2d_new_from_bitmap (clear_bmp,
|
||||||
atlas->texture_format,
|
atlas->texture_format,
|
||||||
&ignore_error);
|
&ignore_error);
|
||||||
|
if (!tex)
|
||||||
|
cogl_error_free (ignore_error);
|
||||||
|
|
||||||
cogl_object_unref (clear_bmp);
|
cogl_object_unref (clear_bmp);
|
||||||
|
|
||||||
g_free (clear_data);
|
g_free (clear_data);
|
||||||
@ -309,13 +312,15 @@ _cogl_atlas_create_texture (CoglAtlas *atlas,
|
|||||||
{
|
{
|
||||||
tex = cogl_texture_2d_new_with_size (ctx,
|
tex = cogl_texture_2d_new_with_size (ctx,
|
||||||
width, height,
|
width, height,
|
||||||
atlas->texture_format,
|
atlas->texture_format);
|
||||||
&ignore_error);
|
if (!cogl_texture_allocate (COGL_TEXTURE (tex), &ignore_error))
|
||||||
|
{
|
||||||
|
cogl_error_free (ignore_error);
|
||||||
|
cogl_object_unref (tex);
|
||||||
|
tex = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tex)
|
|
||||||
cogl_error_free (ignore_error);
|
|
||||||
|
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -547,11 +552,18 @@ _cogl_atlas_copy_rectangle (CoglAtlas *atlas,
|
|||||||
{
|
{
|
||||||
CoglTexture *tex;
|
CoglTexture *tex;
|
||||||
CoglBlitData blit_data;
|
CoglBlitData blit_data;
|
||||||
|
CoglError *ignore_error = NULL;
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NULL);
|
_COGL_GET_CONTEXT (ctx, NULL);
|
||||||
|
|
||||||
/* Create a new texture at the right size */
|
/* Create a new texture at the right size */
|
||||||
tex = cogl_texture_new_with_size (width, height, flags, format);
|
tex = cogl_texture_new_with_size (width, height, flags, format);
|
||||||
|
if (!cogl_texture_allocate (tex, &ignore_error))
|
||||||
|
{
|
||||||
|
cogl_error_free (ignore_error);
|
||||||
|
cogl_object_unref (tex);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Blit the data out of the atlas to the new texture. If FBOs
|
/* Blit the data out of the atlas to the new texture. If FBOs
|
||||||
aren't available this will end up having to copy the entire
|
aren't available this will end up having to copy the entire
|
||||||
|
@ -47,12 +47,13 @@
|
|||||||
#include "cogl-texture-2d-gl.h"
|
#include "cogl-texture-2d-gl.h"
|
||||||
|
|
||||||
CoglTexture *
|
CoglTexture *
|
||||||
cogl_texture_new_with_size (unsigned int width,
|
cogl_texture_new_with_size (unsigned int width,
|
||||||
unsigned int height,
|
unsigned int height,
|
||||||
CoglTextureFlags flags,
|
CoglTextureFlags flags,
|
||||||
CoglPixelFormat internal_format)
|
CoglPixelFormat internal_format)
|
||||||
{
|
{
|
||||||
CoglTexture *tex;
|
CoglTexture *tex;
|
||||||
|
CoglError *skip_error = NULL;
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NULL);
|
_COGL_GET_CONTEXT (ctx, NULL);
|
||||||
|
|
||||||
@ -63,8 +64,18 @@ cogl_texture_new_with_size (unsigned int width,
|
|||||||
/* First try creating a fast-path non-sliced texture */
|
/* First try creating a fast-path non-sliced texture */
|
||||||
tex = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx,
|
tex = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx,
|
||||||
width, height,
|
width, height,
|
||||||
internal_format,
|
internal_format));
|
||||||
NULL));
|
|
||||||
|
/* 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
|
else
|
||||||
tex = NULL;
|
tex = NULL;
|
||||||
@ -83,8 +94,7 @@ cogl_texture_new_with_size (unsigned int width,
|
|||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
max_waste,
|
max_waste,
|
||||||
internal_format,
|
internal_format));
|
||||||
NULL));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return tex;
|
return tex;
|
||||||
|
@ -49,16 +49,15 @@ _cogl_blit_texture_render_begin (CoglBlitData *data)
|
|||||||
CoglFramebuffer *fb;
|
CoglFramebuffer *fb;
|
||||||
CoglPipeline *pipeline;
|
CoglPipeline *pipeline;
|
||||||
unsigned int dst_width, dst_height;
|
unsigned int dst_width, dst_height;
|
||||||
|
CoglError *ignore_error = NULL;
|
||||||
|
|
||||||
offscreen = _cogl_offscreen_new_to_texture_full
|
offscreen = _cogl_offscreen_new_to_texture_full
|
||||||
(data->dst_tex, COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL, 0 /* level */);
|
(data->dst_tex, COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL, 0 /* level */);
|
||||||
|
|
||||||
if (offscreen == NULL)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
fb = COGL_FRAMEBUFFER (offscreen);
|
fb = COGL_FRAMEBUFFER (offscreen);
|
||||||
if (!cogl_framebuffer_allocate (fb, NULL))
|
if (!cogl_framebuffer_allocate (fb, &ignore_error))
|
||||||
{
|
{
|
||||||
|
cogl_error_free (ignore_error);
|
||||||
cogl_object_unref (fb);
|
cogl_object_unref (fb);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -148,6 +147,7 @@ _cogl_blit_framebuffer_begin (CoglBlitData *data)
|
|||||||
CoglContext *ctx = data->src_tex->context;
|
CoglContext *ctx = data->src_tex->context;
|
||||||
CoglOffscreen *dst_offscreen = NULL, *src_offscreen = NULL;
|
CoglOffscreen *dst_offscreen = NULL, *src_offscreen = NULL;
|
||||||
CoglFramebuffer *dst_fb, *src_fb;
|
CoglFramebuffer *dst_fb, *src_fb;
|
||||||
|
CoglError *ignore_error = NULL;
|
||||||
|
|
||||||
/* We can only blit between FBOs if both textures are the same
|
/* We can only blit between FBOs if both textures are the same
|
||||||
format and the blit framebuffer extension is supported */
|
format and the blit framebuffer extension is supported */
|
||||||
@ -158,24 +158,25 @@ _cogl_blit_framebuffer_begin (CoglBlitData *data)
|
|||||||
|
|
||||||
dst_offscreen = _cogl_offscreen_new_to_texture_full
|
dst_offscreen = _cogl_offscreen_new_to_texture_full
|
||||||
(data->dst_tex, COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL, 0 /* level */);
|
(data->dst_tex, COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL, 0 /* level */);
|
||||||
if (dst_offscreen == NULL)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
dst_fb = COGL_FRAMEBUFFER (dst_offscreen);
|
dst_fb = COGL_FRAMEBUFFER (dst_offscreen);
|
||||||
if (!cogl_framebuffer_allocate (dst_fb, NULL))
|
if (!cogl_framebuffer_allocate (dst_fb, &ignore_error))
|
||||||
goto error;
|
{
|
||||||
|
cogl_error_free (ignore_error);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
src_offscreen= _cogl_offscreen_new_to_texture_full
|
src_offscreen= _cogl_offscreen_new_to_texture_full
|
||||||
(data->src_tex,
|
(data->src_tex,
|
||||||
COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL,
|
COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL,
|
||||||
0 /* level */);
|
0 /* level */);
|
||||||
|
|
||||||
if (src_offscreen == NULL)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
src_fb = COGL_FRAMEBUFFER (src_offscreen);
|
src_fb = COGL_FRAMEBUFFER (src_offscreen);
|
||||||
if (!cogl_framebuffer_allocate (src_fb, NULL))
|
if (!cogl_framebuffer_allocate (src_fb, &ignore_error))
|
||||||
goto error;
|
{
|
||||||
|
cogl_error_free (ignore_error);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
data->src_fb = src_fb;
|
data->src_fb = src_fb;
|
||||||
data->dest_fb = dst_fb;
|
data->dest_fb = dst_fb;
|
||||||
@ -220,6 +221,7 @@ _cogl_blit_copy_tex_sub_image_begin (CoglBlitData *data)
|
|||||||
{
|
{
|
||||||
CoglOffscreen *offscreen;
|
CoglOffscreen *offscreen;
|
||||||
CoglFramebuffer *fb;
|
CoglFramebuffer *fb;
|
||||||
|
CoglError *ignore_error = NULL;
|
||||||
|
|
||||||
/* This will only work if the target texture is a CoglTexture2D */
|
/* This will only work if the target texture is a CoglTexture2D */
|
||||||
if (!cogl_is_texture_2d (data->dst_tex))
|
if (!cogl_is_texture_2d (data->dst_tex))
|
||||||
@ -228,12 +230,10 @@ _cogl_blit_copy_tex_sub_image_begin (CoglBlitData *data)
|
|||||||
offscreen = _cogl_offscreen_new_to_texture_full
|
offscreen = _cogl_offscreen_new_to_texture_full
|
||||||
(data->src_tex, COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL, 0 /* level */);
|
(data->src_tex, COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL, 0 /* level */);
|
||||||
|
|
||||||
if (offscreen == NULL)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
fb = COGL_FRAMEBUFFER (offscreen);
|
fb = COGL_FRAMEBUFFER (offscreen);
|
||||||
if (!cogl_framebuffer_allocate (fb, NULL))
|
if (!cogl_framebuffer_allocate (fb, &ignore_error))
|
||||||
{
|
{
|
||||||
|
cogl_error_free (ignore_error);
|
||||||
cogl_object_unref (fb);
|
cogl_object_unref (fb);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -138,14 +138,11 @@ struct _CoglDriverVtable
|
|||||||
void
|
void
|
||||||
(* texture_2d_init) (CoglTexture2D *tex_2d);
|
(* texture_2d_init) (CoglTexture2D *tex_2d);
|
||||||
|
|
||||||
/* Instantiates a new CoglTexture2D object with un-initialized
|
/* Allocates (uninitialized) storage for the given texture according
|
||||||
* storage for a given size and internal format */
|
* to the configured size and format of the texture */
|
||||||
CoglTexture2D *
|
CoglBool
|
||||||
(* texture_2d_new_with_size) (CoglContext *ctx,
|
(* texture_2d_allocate) (CoglTexture *tex,
|
||||||
int width,
|
CoglError **error);
|
||||||
int height,
|
|
||||||
CoglPixelFormat internal_format,
|
|
||||||
CoglError **error);
|
|
||||||
|
|
||||||
/* Instantiates a new CoglTexture2D object with storage initialized
|
/* Instantiates a new CoglTexture2D object with storage initialized
|
||||||
* with the contents of the given bitmap, using the specified
|
* with the contents of the given bitmap, using the specified
|
||||||
|
@ -306,7 +306,7 @@ _cogl_free_framebuffer_stack (GSList *stack);
|
|||||||
CoglOffscreen *
|
CoglOffscreen *
|
||||||
_cogl_offscreen_new_to_texture_full (CoglTexture *texture,
|
_cogl_offscreen_new_to_texture_full (CoglTexture *texture,
|
||||||
CoglOffscreenFlags create_flags,
|
CoglOffscreenFlags create_flags,
|
||||||
unsigned int level);
|
int level);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* _cogl_push_framebuffers:
|
* _cogl_push_framebuffers:
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
#include "cogl-primitives-private.h"
|
#include "cogl-primitives-private.h"
|
||||||
#include "cogl-path-private.h"
|
#include "cogl-path-private.h"
|
||||||
#include "cogl-error-private.h"
|
#include "cogl-error-private.h"
|
||||||
|
#include "cogl-texture-gl-private.h"
|
||||||
|
|
||||||
typedef struct _CoglFramebufferStackEntry
|
typedef struct _CoglFramebufferStackEntry
|
||||||
{
|
{
|
||||||
@ -569,48 +570,24 @@ _cogl_framebuffer_flush_dependency_journals (CoglFramebuffer *framebuffer)
|
|||||||
CoglOffscreen *
|
CoglOffscreen *
|
||||||
_cogl_offscreen_new_to_texture_full (CoglTexture *texture,
|
_cogl_offscreen_new_to_texture_full (CoglTexture *texture,
|
||||||
CoglOffscreenFlags create_flags,
|
CoglOffscreenFlags create_flags,
|
||||||
unsigned int level)
|
int level)
|
||||||
{
|
{
|
||||||
CoglContext *ctx = texture->context;
|
CoglContext *ctx = texture->context;
|
||||||
CoglOffscreen *offscreen;
|
CoglOffscreen *offscreen;
|
||||||
CoglFramebuffer *fb;
|
CoglFramebuffer *fb;
|
||||||
int level_width;
|
int level_width;
|
||||||
int level_height;
|
int level_height;
|
||||||
int i;
|
|
||||||
CoglOffscreen *ret;
|
CoglOffscreen *ret;
|
||||||
|
|
||||||
if (!cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN))
|
_COGL_RETURN_VAL_IF_FAIL (cogl_is_texture (texture), NULL);
|
||||||
return NULL;
|
_COGL_RETURN_VAL_IF_FAIL (level < _cogl_texture_get_n_levels (texture),
|
||||||
|
NULL);
|
||||||
|
|
||||||
/* Make texture is a valid texture object */
|
_cogl_texture_get_level_size (texture,
|
||||||
if (!cogl_is_texture (texture))
|
level,
|
||||||
return NULL;
|
&level_width,
|
||||||
|
&level_height,
|
||||||
/* The texture must not be sliced */
|
NULL);
|
||||||
if (cogl_texture_is_sliced (texture))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* Calculate the size of the texture at this mipmap level to ensure
|
|
||||||
that it's a valid level */
|
|
||||||
level_width = cogl_texture_get_width (texture);
|
|
||||||
level_height = cogl_texture_get_height (texture);
|
|
||||||
|
|
||||||
for (i = 0; i < level; i++)
|
|
||||||
{
|
|
||||||
/* If neither dimension can be further divided then the level is
|
|
||||||
invalid */
|
|
||||||
if (level_width == 1 && level_height == 1)
|
|
||||||
{
|
|
||||||
g_warning ("Invalid texture level passed to "
|
|
||||||
"_cogl_offscreen_new_to_texture_full");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (level_width > 1)
|
|
||||||
level_width >>= 1;
|
|
||||||
if (level_height > 1)
|
|
||||||
level_height >>= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
offscreen = g_new0 (CoglOffscreen, 1);
|
offscreen = g_new0 (CoglOffscreen, 1);
|
||||||
offscreen->texture = cogl_object_ref (texture);
|
offscreen->texture = cogl_object_ref (texture);
|
||||||
@ -688,7 +665,29 @@ cogl_framebuffer_allocate (CoglFramebuffer *framebuffer,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
CoglContext *ctx = framebuffer->context;
|
CoglContext *ctx = framebuffer->context;
|
||||||
if (!ctx->driver_vtable->offscreen_allocate (COGL_OFFSCREEN (framebuffer), error))
|
CoglOffscreen *offscreen = COGL_OFFSCREEN (framebuffer);
|
||||||
|
|
||||||
|
if (!cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN))
|
||||||
|
{
|
||||||
|
_cogl_set_error (error, COGL_SYSTEM_ERROR,
|
||||||
|
COGL_SYSTEM_ERROR_UNSUPPORTED,
|
||||||
|
"Offscreen framebuffers not supported by system");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cogl_texture_is_sliced (offscreen->texture))
|
||||||
|
{
|
||||||
|
_cogl_set_error (error, COGL_SYSTEM_ERROR,
|
||||||
|
COGL_SYSTEM_ERROR_UNSUPPORTED,
|
||||||
|
"Can't create offscreen framebuffer from "
|
||||||
|
"sliced texture");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cogl_texture_allocate (offscreen->texture, error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!ctx->driver_vtable->offscreen_allocate (offscreen, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,6 +259,15 @@ cogl_sub_texture_new (CoglContext *ctx,
|
|||||||
return _cogl_sub_texture_object_new (sub_tex);
|
return _cogl_sub_texture_object_new (sub_tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CoglBool
|
||||||
|
_cogl_sub_texture_allocate (CoglTexture *tex,
|
||||||
|
CoglError **error)
|
||||||
|
{
|
||||||
|
CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex);
|
||||||
|
|
||||||
|
return cogl_texture_allocate (sub_tex->full_texture, error);
|
||||||
|
}
|
||||||
|
|
||||||
CoglTexture *
|
CoglTexture *
|
||||||
cogl_sub_texture_get_parent (CoglSubTexture *sub_texture)
|
cogl_sub_texture_get_parent (CoglSubTexture *sub_texture)
|
||||||
{
|
{
|
||||||
@ -433,6 +442,7 @@ static const CoglTextureVtable
|
|||||||
cogl_sub_texture_vtable =
|
cogl_sub_texture_vtable =
|
||||||
{
|
{
|
||||||
FALSE, /* not primitive */
|
FALSE, /* not primitive */
|
||||||
|
_cogl_sub_texture_allocate,
|
||||||
_cogl_sub_texture_set_region,
|
_cogl_sub_texture_set_region,
|
||||||
NULL, /* get_data */
|
NULL, /* get_data */
|
||||||
_cogl_sub_texture_foreach_sub_texture_in_region,
|
_cogl_sub_texture_foreach_sub_texture_in_region,
|
||||||
|
@ -39,7 +39,7 @@ struct _CoglTexture2D
|
|||||||
|
|
||||||
/* The internal format of the GL texture represented as a
|
/* The internal format of the GL texture represented as a
|
||||||
CoglPixelFormat */
|
CoglPixelFormat */
|
||||||
CoglPixelFormat format;
|
CoglPixelFormat internal_format;
|
||||||
|
|
||||||
CoglBool auto_mipmap;
|
CoglBool auto_mipmap;
|
||||||
CoglBool mipmaps_dirty;
|
CoglBool mipmaps_dirty;
|
||||||
|
@ -38,6 +38,7 @@ struct _CoglTexture2DSliced
|
|||||||
GArray *slice_y_spans;
|
GArray *slice_y_spans;
|
||||||
GArray *slice_textures;
|
GArray *slice_textures;
|
||||||
int max_waste;
|
int max_waste;
|
||||||
|
CoglPixelFormat internal_format;
|
||||||
};
|
};
|
||||||
|
|
||||||
CoglTexture2DSliced *
|
CoglTexture2DSliced *
|
||||||
|
@ -656,20 +656,18 @@ _cogl_texture_2d_sliced_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static CoglBool
|
static CoglBool
|
||||||
_cogl_texture_2d_sliced_slices_create (CoglContext *ctx,
|
_cogl_texture_2d_sliced_setup_spans (CoglContext *ctx,
|
||||||
CoglTexture2DSliced *tex_2ds,
|
CoglTexture2DSliced *tex_2ds,
|
||||||
int width, int height,
|
int width,
|
||||||
CoglPixelFormat format)
|
int height,
|
||||||
|
int max_waste,
|
||||||
|
CoglPixelFormat format,
|
||||||
|
CoglError **error)
|
||||||
{
|
{
|
||||||
int max_width;
|
int max_width;
|
||||||
int max_height;
|
int max_height;
|
||||||
CoglTexture2D **slice_textures;
|
|
||||||
int n_x_slices;
|
int n_x_slices;
|
||||||
int n_y_slices;
|
int n_y_slices;
|
||||||
int n_slices;
|
|
||||||
int x, y;
|
|
||||||
CoglSpan *x_span;
|
|
||||||
CoglSpan *y_span;
|
|
||||||
GLenum gl_intformat;
|
GLenum gl_intformat;
|
||||||
GLenum gl_format;
|
GLenum gl_format;
|
||||||
GLenum gl_type;
|
GLenum gl_type;
|
||||||
@ -697,7 +695,7 @@ _cogl_texture_2d_sliced_slices_create (CoglContext *ctx,
|
|||||||
&gl_type);
|
&gl_type);
|
||||||
|
|
||||||
/* Negative number means no slicing forced by the user */
|
/* Negative number means no slicing forced by the user */
|
||||||
if (tex_2ds->max_waste <= -1)
|
if (max_waste <= -1)
|
||||||
{
|
{
|
||||||
CoglSpan span;
|
CoglSpan span;
|
||||||
|
|
||||||
@ -710,6 +708,13 @@ _cogl_texture_2d_sliced_slices_create (CoglContext *ctx,
|
|||||||
max_width,
|
max_width,
|
||||||
max_height))
|
max_height))
|
||||||
{
|
{
|
||||||
|
_cogl_set_error (error,
|
||||||
|
COGL_TEXTURE_ERROR,
|
||||||
|
COGL_TEXTURE_ERROR_SIZE,
|
||||||
|
"Sliced texture size of %d x %d not possible "
|
||||||
|
"with max waste set to -1",
|
||||||
|
width,
|
||||||
|
height);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -753,16 +758,25 @@ _cogl_texture_2d_sliced_slices_create (CoglContext *ctx,
|
|||||||
max_height /= 2;
|
max_height /= 2;
|
||||||
|
|
||||||
if (max_width == 0 || max_height == 0)
|
if (max_width == 0 || max_height == 0)
|
||||||
return FALSE;
|
{
|
||||||
|
/* Maybe it would be ok to just g_warn_if_reached() for this
|
||||||
|
* codepath */
|
||||||
|
_cogl_set_error (error,
|
||||||
|
COGL_TEXTURE_ERROR,
|
||||||
|
COGL_TEXTURE_ERROR_SIZE,
|
||||||
|
"No suitable slice geometry found");
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine the slices required to cover the bitmap area */
|
/* Determine the slices required to cover the bitmap area */
|
||||||
n_x_slices = slices_for_size (width,
|
n_x_slices = slices_for_size (width,
|
||||||
max_width, tex_2ds->max_waste,
|
max_width, max_waste,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
n_y_slices = slices_for_size (height,
|
n_y_slices = slices_for_size (height,
|
||||||
max_height, tex_2ds->max_waste,
|
max_height, max_waste,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
/* Init span arrays with reserved size */
|
/* Init span arrays with reserved size */
|
||||||
@ -776,64 +790,20 @@ _cogl_texture_2d_sliced_slices_create (CoglContext *ctx,
|
|||||||
|
|
||||||
/* Fill span arrays with info */
|
/* Fill span arrays with info */
|
||||||
slices_for_size (width,
|
slices_for_size (width,
|
||||||
max_width, tex_2ds->max_waste,
|
max_width, max_waste,
|
||||||
tex_2ds->slice_x_spans);
|
tex_2ds->slice_x_spans);
|
||||||
|
|
||||||
slices_for_size (height,
|
slices_for_size (height,
|
||||||
max_height, tex_2ds->max_waste,
|
max_height, max_waste,
|
||||||
tex_2ds->slice_y_spans);
|
tex_2ds->slice_y_spans);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Init and resize GL handle array */
|
|
||||||
n_slices = n_x_slices * n_y_slices;
|
|
||||||
|
|
||||||
tex_2ds->slice_textures = g_array_sized_new (FALSE, FALSE,
|
|
||||||
sizeof (CoglTexture2D *),
|
|
||||||
n_slices);
|
|
||||||
|
|
||||||
g_array_set_size (tex_2ds->slice_textures, n_slices);
|
|
||||||
|
|
||||||
slice_textures = (CoglTexture2D **) tex_2ds->slice_textures->data;
|
|
||||||
|
|
||||||
/* Init each GL texture object */
|
|
||||||
for (y = 0; y < n_y_slices; ++y)
|
|
||||||
{
|
|
||||||
y_span = &g_array_index (tex_2ds->slice_y_spans, CoglSpan, y);
|
|
||||||
|
|
||||||
for (x = 0; x < n_x_slices; ++x)
|
|
||||||
{
|
|
||||||
CoglError *error = NULL;
|
|
||||||
x_span = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, x);
|
|
||||||
|
|
||||||
COGL_NOTE (SLICING, "CREATE SLICE (%d,%d)\tsize (%d,%d)",
|
|
||||||
x, y,
|
|
||||||
(int)(x_span->size - x_span->waste),
|
|
||||||
(int)(y_span->size - y_span->waste));
|
|
||||||
|
|
||||||
slice_textures[y * n_x_slices + x] =
|
|
||||||
cogl_texture_2d_new_with_size (ctx, x_span->size, y_span->size,
|
|
||||||
format, &error);
|
|
||||||
if (!slice_textures[y * n_x_slices + x])
|
|
||||||
{
|
|
||||||
g_array_set_size (tex_2ds->slice_textures, y * n_x_slices + x);
|
|
||||||
cogl_error_free (error);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_cogl_texture_2d_sliced_slices_free (CoglTexture2DSliced *tex_2ds)
|
_cogl_texture_2d_sliced_slices_free (CoglTexture2DSliced *tex_2ds)
|
||||||
{
|
{
|
||||||
if (tex_2ds->slice_x_spans != NULL)
|
|
||||||
g_array_free (tex_2ds->slice_x_spans, TRUE);
|
|
||||||
|
|
||||||
if (tex_2ds->slice_y_spans != NULL)
|
|
||||||
g_array_free (tex_2ds->slice_y_spans, TRUE);
|
|
||||||
|
|
||||||
if (tex_2ds->slice_textures != NULL)
|
if (tex_2ds->slice_textures != NULL)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -854,6 +824,12 @@ _cogl_texture_2d_sliced_free (CoglTexture2DSliced *tex_2ds)
|
|||||||
{
|
{
|
||||||
_cogl_texture_2d_sliced_slices_free (tex_2ds);
|
_cogl_texture_2d_sliced_slices_free (tex_2ds);
|
||||||
|
|
||||||
|
if (tex_2ds->slice_x_spans != NULL)
|
||||||
|
g_array_free (tex_2ds->slice_x_spans, TRUE);
|
||||||
|
|
||||||
|
if (tex_2ds->slice_y_spans != NULL)
|
||||||
|
g_array_free (tex_2ds->slice_y_spans, TRUE);
|
||||||
|
|
||||||
/* Chain up */
|
/* Chain up */
|
||||||
_cogl_texture_free (COGL_TEXTURE (tex_2ds));
|
_cogl_texture_free (COGL_TEXTURE (tex_2ds));
|
||||||
}
|
}
|
||||||
@ -863,76 +839,148 @@ _cogl_texture_2d_sliced_init_base (CoglContext *ctx,
|
|||||||
CoglTexture2DSliced *tex_2ds,
|
CoglTexture2DSliced *tex_2ds,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
CoglPixelFormat internal_format)
|
int max_waste,
|
||||||
|
CoglPixelFormat internal_format,
|
||||||
|
CoglError **error)
|
||||||
{
|
{
|
||||||
CoglTexture *tex = COGL_TEXTURE (tex_2ds);
|
CoglTexture *tex = COGL_TEXTURE (tex_2ds);
|
||||||
|
|
||||||
_cogl_texture_init (tex, ctx, width, height, &cogl_texture_2d_sliced_vtable);
|
_cogl_texture_init (tex, ctx, width, height, &cogl_texture_2d_sliced_vtable);
|
||||||
|
|
||||||
tex_2ds->slice_x_spans = NULL;
|
tex_2ds->max_waste = max_waste;
|
||||||
tex_2ds->slice_y_spans = NULL;
|
tex_2ds->internal_format = internal_format;
|
||||||
tex_2ds->slice_textures = NULL;
|
|
||||||
|
|
||||||
/* Create slices for the given format and size */
|
return _cogl_texture_2d_sliced_setup_spans (ctx, tex_2ds,
|
||||||
if (!_cogl_texture_2d_sliced_slices_create (ctx,
|
width, height,
|
||||||
tex_2ds,
|
max_waste,
|
||||||
width,
|
internal_format,
|
||||||
height,
|
error);
|
||||||
internal_format))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CoglTexture2DSliced *
|
CoglTexture2DSliced *
|
||||||
cogl_texture_2d_sliced_new_with_size (CoglContext *ctx,
|
cogl_texture_2d_sliced_new_with_size (CoglContext *ctx,
|
||||||
unsigned int width,
|
int width,
|
||||||
unsigned int height,
|
int height,
|
||||||
int max_waste,
|
int max_waste,
|
||||||
CoglPixelFormat internal_format,
|
CoglPixelFormat internal_format)
|
||||||
CoglError **error)
|
|
||||||
{
|
{
|
||||||
CoglTexture2DSliced *tex_2ds;
|
CoglTexture2DSliced *tex_2ds;
|
||||||
|
CoglError *ignore_error = NULL;
|
||||||
|
|
||||||
/* Since no data, we need some internal format */
|
/* Since no data, we need some internal format */
|
||||||
if (internal_format == COGL_PIXEL_FORMAT_ANY)
|
if (internal_format == COGL_PIXEL_FORMAT_ANY)
|
||||||
internal_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE;
|
internal_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE;
|
||||||
|
|
||||||
/* Init texture with empty bitmap */
|
/* Init texture with empty bitmap */
|
||||||
tex_2ds = g_new (CoglTexture2DSliced, 1);
|
tex_2ds = g_new0 (CoglTexture2DSliced, 1);
|
||||||
|
|
||||||
tex_2ds->max_waste = max_waste;
|
|
||||||
|
|
||||||
if (!_cogl_texture_2d_sliced_init_base (ctx,
|
if (!_cogl_texture_2d_sliced_init_base (ctx,
|
||||||
tex_2ds,
|
tex_2ds,
|
||||||
width, height,
|
width, height,
|
||||||
internal_format))
|
max_waste,
|
||||||
|
internal_format,
|
||||||
|
&ignore_error))
|
||||||
{
|
{
|
||||||
_cogl_texture_2d_sliced_free (tex_2ds);
|
/* In this case we failed to find any suitable slicing geometry
|
||||||
_cogl_set_error (error,
|
* for the given texture size.
|
||||||
COGL_SYSTEM_ERROR,
|
*
|
||||||
COGL_SYSTEM_ERROR_NO_MEMORY,
|
* We don't need to do anything with the error here since it
|
||||||
"Not enough memory to allocate texture slices");
|
* will be picked up on later when trying to allocate the
|
||||||
return NULL;
|
* texture.
|
||||||
|
*/
|
||||||
|
cogl_error_free (ignore_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* NB: We need to be sure that cogl_texture_is_sliced() will work
|
||||||
|
* correctly before returning since
|
||||||
|
* cogl_framebuffer_allocate() uses this api to determine
|
||||||
|
* if a texture can be rendered to which may be before the
|
||||||
|
* slices have been allocated.
|
||||||
|
*/
|
||||||
|
|
||||||
return _cogl_texture_2d_sliced_object_new (tex_2ds);
|
return _cogl_texture_2d_sliced_object_new (tex_2ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CoglBool
|
||||||
|
_cogl_texture_2d_sliced_allocate (CoglTexture *tex,
|
||||||
|
CoglError **error)
|
||||||
|
{
|
||||||
|
CoglContext *ctx = tex->context;
|
||||||
|
CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex);
|
||||||
|
int n_x_slices;
|
||||||
|
int n_y_slices;
|
||||||
|
int n_slices;
|
||||||
|
int x, y;
|
||||||
|
CoglPixelFormat format = tex_2ds->internal_format;
|
||||||
|
CoglSpan *x_span;
|
||||||
|
CoglSpan *y_span;
|
||||||
|
|
||||||
|
if (!tex_2ds->slice_x_spans || !tex_2ds->slice_y_spans)
|
||||||
|
{
|
||||||
|
_cogl_set_error (error,
|
||||||
|
COGL_TEXTURE_ERROR,
|
||||||
|
COGL_TEXTURE_ERROR_SIZE,
|
||||||
|
"Couldn't find suitable slicing geometry "
|
||||||
|
"for given size");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
n_x_slices = tex_2ds->slice_x_spans->len;
|
||||||
|
n_y_slices = tex_2ds->slice_y_spans->len;
|
||||||
|
n_slices = n_x_slices * n_y_slices;
|
||||||
|
|
||||||
|
tex_2ds->slice_textures = g_array_sized_new (FALSE, FALSE,
|
||||||
|
sizeof (CoglTexture2D *),
|
||||||
|
n_slices);
|
||||||
|
|
||||||
|
g_array_set_size (tex_2ds->slice_textures, n_slices);
|
||||||
|
|
||||||
|
/* Allocate each slice */
|
||||||
|
for (y = 0; y < n_y_slices; ++y)
|
||||||
|
{
|
||||||
|
y_span = &g_array_index (tex_2ds->slice_y_spans, CoglSpan, y);
|
||||||
|
|
||||||
|
for (x = 0; x < n_x_slices; ++x)
|
||||||
|
{
|
||||||
|
CoglTexture *slice;
|
||||||
|
|
||||||
|
x_span = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, x);
|
||||||
|
|
||||||
|
COGL_NOTE (SLICING, "CREATE SLICE (%d,%d)\tsize (%d,%d)",
|
||||||
|
x, y,
|
||||||
|
(int)(x_span->size - x_span->waste),
|
||||||
|
(int)(y_span->size - y_span->waste));
|
||||||
|
|
||||||
|
slice = COGL_TEXTURE (
|
||||||
|
cogl_texture_2d_new_with_size (ctx,
|
||||||
|
x_span->size, y_span->size,
|
||||||
|
format));
|
||||||
|
g_array_append_val (tex_2ds->slice_textures, slice);
|
||||||
|
if (!cogl_texture_allocate (slice, error))
|
||||||
|
{
|
||||||
|
_cogl_texture_2d_sliced_slices_free (tex_2ds);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
CoglTexture2DSliced *
|
CoglTexture2DSliced *
|
||||||
_cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp,
|
_cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp,
|
||||||
CoglTextureFlags flags,
|
CoglTextureFlags flags,
|
||||||
CoglPixelFormat internal_format,
|
CoglPixelFormat internal_format,
|
||||||
CoglError **error)
|
CoglError **error)
|
||||||
{
|
{
|
||||||
|
CoglContext *ctx;
|
||||||
CoglTexture2DSliced *tex_2ds;
|
CoglTexture2DSliced *tex_2ds;
|
||||||
CoglBitmap *dst_bmp;
|
CoglBitmap *dst_bmp;
|
||||||
GLenum gl_intformat;
|
GLenum gl_intformat;
|
||||||
GLenum gl_format;
|
GLenum gl_format;
|
||||||
GLenum gl_type;
|
GLenum gl_type;
|
||||||
int width, height;
|
int width, height, max_waste;
|
||||||
CoglContext *ctx;
|
int i;
|
||||||
int i;
|
|
||||||
|
|
||||||
_COGL_RETURN_VAL_IF_FAIL (cogl_is_bitmap (bmp), NULL);
|
_COGL_RETURN_VAL_IF_FAIL (cogl_is_bitmap (bmp), NULL);
|
||||||
|
|
||||||
@ -945,9 +993,9 @@ _cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp,
|
|||||||
tex_2ds = g_new0 (CoglTexture2DSliced, 1);
|
tex_2ds = g_new0 (CoglTexture2DSliced, 1);
|
||||||
|
|
||||||
if (flags & COGL_TEXTURE_NO_SLICING)
|
if (flags & COGL_TEXTURE_NO_SLICING)
|
||||||
tex_2ds->max_waste = -1;
|
max_waste = -1;
|
||||||
else
|
else
|
||||||
tex_2ds->max_waste = COGL_TEXTURE_MAX_WASTE;
|
max_waste = COGL_TEXTURE_MAX_WASTE;
|
||||||
|
|
||||||
dst_bmp = _cogl_texture_prepare_for_upload (bmp,
|
dst_bmp = _cogl_texture_prepare_for_upload (bmp,
|
||||||
internal_format,
|
internal_format,
|
||||||
@ -962,10 +1010,17 @@ _cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* NB: we may fail to find any suitable slicing geometry for the
|
||||||
|
* given texture size. */
|
||||||
if (!_cogl_texture_2d_sliced_init_base (ctx,
|
if (!_cogl_texture_2d_sliced_init_base (ctx,
|
||||||
tex_2ds,
|
tex_2ds,
|
||||||
width, height,
|
width, height,
|
||||||
internal_format))
|
max_waste,
|
||||||
|
internal_format,
|
||||||
|
error))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (!cogl_texture_allocate (COGL_TEXTURE (tex_2ds), error))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!_cogl_texture_2d_sliced_upload_to_gl (tex_2ds,
|
if (!_cogl_texture_2d_sliced_upload_to_gl (tex_2ds,
|
||||||
@ -1054,6 +1109,7 @@ _cogl_texture_2d_sliced_new_from_foreign (CoglContext *ctx,
|
|||||||
&cogl_texture_2d_sliced_vtable);
|
&cogl_texture_2d_sliced_vtable);
|
||||||
|
|
||||||
tex_2ds->max_waste = 0;
|
tex_2ds->max_waste = 0;
|
||||||
|
tex_2ds->internal_format = format;
|
||||||
|
|
||||||
/* Create slice arrays */
|
/* Create slice arrays */
|
||||||
tex_2ds->slice_x_spans =
|
tex_2ds->slice_x_spans =
|
||||||
@ -1081,6 +1137,8 @@ _cogl_texture_2d_sliced_new_from_foreign (CoglContext *ctx,
|
|||||||
|
|
||||||
g_array_append_val (tex_2ds->slice_textures, tex_2d);
|
g_array_append_val (tex_2ds->slice_textures, tex_2d);
|
||||||
|
|
||||||
|
_cogl_texture_set_allocated (COGL_TEXTURE (tex_2ds), TRUE);
|
||||||
|
|
||||||
return _cogl_texture_2d_sliced_object_new (tex_2ds);
|
return _cogl_texture_2d_sliced_object_new (tex_2ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1112,13 +1170,23 @@ _cogl_texture_2d_sliced_is_sliced (CoglTexture *tex)
|
|||||||
{
|
{
|
||||||
CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex);
|
CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex);
|
||||||
|
|
||||||
if (tex_2ds->slice_textures == NULL)
|
/* It's possible that we failed to calculate valid slicing geometry
|
||||||
|
* when initializing the texture due to the max_waste size and in
|
||||||
|
* this case we report that the texture is not sliced.
|
||||||
|
*
|
||||||
|
* In this case though we know that we will be throwing an error
|
||||||
|
* when this texture is later allocated so it shouldn't really
|
||||||
|
* matter what we report here since the texture won't be used in the
|
||||||
|
* end.
|
||||||
|
*/
|
||||||
|
if (!tex_2ds->slice_x_spans || !tex_2ds->slice_y_spans)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (tex_2ds->slice_textures->len <= 1)
|
if (tex_2ds->slice_x_spans->len != 1 ||
|
||||||
|
tex_2ds->slice_y_spans->len != 1)
|
||||||
|
return TRUE;
|
||||||
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static CoglBool
|
static CoglBool
|
||||||
@ -1223,12 +1291,10 @@ _cogl_texture_2d_sliced_gl_flush_legacy_texobj_filters (CoglTexture *tex,
|
|||||||
GLenum mag_filter)
|
GLenum mag_filter)
|
||||||
{
|
{
|
||||||
CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex);
|
CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex);
|
||||||
CoglTexture2D *slice_tex;
|
CoglTexture2D *slice_tex;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Make sure slices were created */
|
_COGL_RETURN_IF_FAIL (tex_2ds->slice_textures != NULL);
|
||||||
if (tex_2ds->slice_textures == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Apply new filters to every slice. The slice texture itself should
|
/* Apply new filters to every slice. The slice texture itself should
|
||||||
cache the value and avoid resubmitting the same filter value to
|
cache the value and avoid resubmitting the same filter value to
|
||||||
@ -1246,11 +1312,9 @@ _cogl_texture_2d_sliced_pre_paint (CoglTexture *tex,
|
|||||||
CoglTexturePrePaintFlags flags)
|
CoglTexturePrePaintFlags flags)
|
||||||
{
|
{
|
||||||
CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex);
|
CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Make sure slices were created */
|
_COGL_RETURN_IF_FAIL (tex_2ds->slice_textures != NULL);
|
||||||
if (tex_2ds->slice_textures == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Pass the pre-paint on to every slice */
|
/* Pass the pre-paint on to every slice */
|
||||||
for (i = 0; i < tex_2ds->slice_textures->len; i++)
|
for (i = 0; i < tex_2ds->slice_textures->len; i++)
|
||||||
@ -1267,9 +1331,7 @@ _cogl_texture_2d_sliced_ensure_non_quad_rendering (CoglTexture *tex)
|
|||||||
CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex);
|
CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Make sure slices were created */
|
_COGL_RETURN_IF_FAIL (tex_2ds->slice_textures != NULL);
|
||||||
if (tex_2ds->slice_textures == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Pass the call on to every slice */
|
/* Pass the call on to every slice */
|
||||||
for (i = 0; i < tex_2ds->slice_textures->len; i++)
|
for (i = 0; i < tex_2ds->slice_textures->len; i++)
|
||||||
@ -1327,15 +1389,8 @@ static CoglPixelFormat
|
|||||||
_cogl_texture_2d_sliced_get_format (CoglTexture *tex)
|
_cogl_texture_2d_sliced_get_format (CoglTexture *tex)
|
||||||
{
|
{
|
||||||
CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex);
|
CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex);
|
||||||
CoglTexture2D *slice_tex;
|
|
||||||
|
|
||||||
/* Make sure slices were created */
|
return tex_2ds->internal_format;
|
||||||
if (tex_2ds->slice_textures == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Pass the call on to the first slice */
|
|
||||||
slice_tex = g_array_index (tex_2ds->slice_textures, CoglTexture2D *, 0);
|
|
||||||
return cogl_texture_get_format (COGL_TEXTURE (slice_tex));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLenum
|
static GLenum
|
||||||
@ -1344,9 +1399,8 @@ _cogl_texture_2d_sliced_get_gl_format (CoglTexture *tex)
|
|||||||
CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex);
|
CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex);
|
||||||
CoglTexture2D *slice_tex;
|
CoglTexture2D *slice_tex;
|
||||||
|
|
||||||
/* Make sure slices were created */
|
/* Assert that we've allocated our slices at this point */
|
||||||
if (tex_2ds->slice_textures == NULL)
|
cogl_texture_allocate (tex, NULL); /* (abort on error) */
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Pass the call on to the first slice */
|
/* Pass the call on to the first slice */
|
||||||
slice_tex = g_array_index (tex_2ds->slice_textures, CoglTexture2D *, 0);
|
slice_tex = g_array_index (tex_2ds->slice_textures, CoglTexture2D *, 0);
|
||||||
@ -1363,6 +1417,7 @@ static const CoglTextureVtable
|
|||||||
cogl_texture_2d_sliced_vtable =
|
cogl_texture_2d_sliced_vtable =
|
||||||
{
|
{
|
||||||
FALSE, /* not primitive */
|
FALSE, /* not primitive */
|
||||||
|
_cogl_texture_2d_sliced_allocate,
|
||||||
_cogl_texture_2d_sliced_set_region,
|
_cogl_texture_2d_sliced_set_region,
|
||||||
NULL, /* get_data */
|
NULL, /* get_data */
|
||||||
_cogl_texture_2d_sliced_foreach_sub_texture_in_region,
|
_cogl_texture_2d_sliced_foreach_sub_texture_in_region,
|
||||||
|
@ -70,32 +70,48 @@ typedef struct _CoglTexture2DSliced CoglTexture2DSliced;
|
|||||||
* @width: The virtual width of your sliced texture.
|
* @width: The virtual width of your sliced texture.
|
||||||
* @height: The virtual height of your sliced texture.
|
* @height: The virtual height of your sliced texture.
|
||||||
* @max_waste: The threshold of how wide a strip of wasted texels
|
* @max_waste: The threshold of how wide a strip of wasted texels
|
||||||
* are allowed in the non-power-of-two textures before
|
* are allowed along the right and bottom textures before
|
||||||
* they must be sliced to reduce the amount of waste.
|
* they must be sliced to reduce the amount of waste. A
|
||||||
|
* negative can be passed to disable slicing.
|
||||||
* @internal_format: The format of the texture
|
* @internal_format: The format of the texture
|
||||||
* @error: A #CoglError for exceptions.
|
|
||||||
*
|
*
|
||||||
* Creates a #CoglTexture2DSliced that may internally be comprised of
|
* Creates a #CoglTexture2DSliced that may internally be comprised of
|
||||||
* 1 or more #CoglTexture2D textures with power-of-two sizes.
|
* 1 or more #CoglTexture2D textures depending on GPU limitations.
|
||||||
* @max_waste is used as a threshold for recursively slicing the
|
* For example if the GPU only supports power-of-two sized textures
|
||||||
* right-most or bottom-most slices into smaller power-of-two sizes
|
* then a sliced texture will turn a non-power-of-two size into a
|
||||||
* until the wasted padding at the bottom and right of the
|
* combination of smaller power-of-two sized textures. If the
|
||||||
* power-of-two textures is less than specified.
|
* requested texture size is larger than is supported by the hardware
|
||||||
|
* then the texture will be sliced into smaller textures that can be
|
||||||
|
* accessed by the hardware.
|
||||||
*
|
*
|
||||||
* Returns: A newly allocated #CoglTexture2DSliced or if there was
|
* @max_waste is used as a threshold for recursively slicing the
|
||||||
* an error allocating any of the internal slices %NULL is
|
* right-most or bottom-most slices into smaller sizes until the
|
||||||
* returned and @error is updated.
|
* wasted padding at the bottom and right of the textures is less than
|
||||||
|
* specified. A negative @max_waste will disable slicing.
|
||||||
|
*
|
||||||
|
* 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>It's possible for the allocation of a sliced texture to fail
|
||||||
|
* later due to impossible slicing constraints if a negative
|
||||||
|
* @max_waste value is given. If the given virtual texture size size
|
||||||
|
* is larger than is supported by the hardware but slicing is disabled
|
||||||
|
* the texture size would be too large to handle.</note>
|
||||||
|
*
|
||||||
|
* Returns: A new #CoglTexture2DSliced object with no storage
|
||||||
|
* allocated yet.
|
||||||
*
|
*
|
||||||
* Since: 1.10
|
* Since: 1.10
|
||||||
* Stability: unstable
|
* Stability: unstable
|
||||||
*/
|
*/
|
||||||
CoglTexture2DSliced *
|
CoglTexture2DSliced *
|
||||||
cogl_texture_2d_sliced_new_with_size (CoglContext *ctx,
|
cogl_texture_2d_sliced_new_with_size (CoglContext *ctx,
|
||||||
unsigned int width,
|
int width,
|
||||||
unsigned int height,
|
int height,
|
||||||
int max_waste,
|
int max_waste,
|
||||||
CoglPixelFormat internal_format,
|
CoglPixelFormat internal_format);
|
||||||
CoglError **error);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cogl_is_texture_2d_sliced:
|
* cogl_is_texture_2d_sliced:
|
||||||
|
@ -119,7 +119,7 @@ _cogl_texture_2d_create_base (CoglContext *ctx,
|
|||||||
|
|
||||||
tex_2d->is_foreign = FALSE;
|
tex_2d->is_foreign = FALSE;
|
||||||
|
|
||||||
tex_2d->format = internal_format;
|
tex_2d->internal_format = internal_format;
|
||||||
|
|
||||||
ctx->driver_vtable->texture_2d_init (tex_2d);
|
ctx->driver_vtable->texture_2d_init (tex_2d);
|
||||||
|
|
||||||
@ -130,27 +130,23 @@ CoglTexture2D *
|
|||||||
cogl_texture_2d_new_with_size (CoglContext *ctx,
|
cogl_texture_2d_new_with_size (CoglContext *ctx,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
CoglPixelFormat internal_format,
|
CoglPixelFormat internal_format)
|
||||||
CoglError **error)
|
|
||||||
{
|
{
|
||||||
/* Since no data, we need some internal format */
|
/* Since no data, we need some internal format */
|
||||||
if (internal_format == COGL_PIXEL_FORMAT_ANY)
|
if (internal_format == COGL_PIXEL_FORMAT_ANY)
|
||||||
internal_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE;
|
internal_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE;
|
||||||
|
|
||||||
if (!_cogl_texture_2d_can_create (ctx, width, height, internal_format))
|
return _cogl_texture_2d_create_base (ctx,
|
||||||
{
|
width, height,
|
||||||
_cogl_set_error (error, COGL_TEXTURE_ERROR,
|
internal_format);
|
||||||
COGL_TEXTURE_ERROR_SIZE,
|
}
|
||||||
"Failed to create texture 2d due to size/format"
|
|
||||||
" constraints");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ctx->driver_vtable->texture_2d_new_with_size (ctx,
|
static CoglBool
|
||||||
width,
|
_cogl_texture_2d_allocate (CoglTexture *tex,
|
||||||
height,
|
CoglError **error)
|
||||||
internal_format,
|
{
|
||||||
error);
|
CoglContext *ctx = tex->context;
|
||||||
|
return ctx->driver_vtable->texture_2d_allocate (tex, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
CoglTexture2D *
|
CoglTexture2D *
|
||||||
@ -178,7 +174,6 @@ cogl_texture_2d_new_from_bitmap (CoglBitmap *bmp,
|
|||||||
"Failed to create texture 2d due to size/format"
|
"Failed to create texture 2d due to size/format"
|
||||||
" constraints");
|
" constraints");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx->driver_vtable->texture_2d_new_from_bitmap (bmp,
|
return ctx->driver_vtable->texture_2d_new_from_bitmap (bmp,
|
||||||
@ -350,7 +345,11 @@ _cogl_texture_2d_copy_from_framebuffer (CoglTexture2D *tex_2d,
|
|||||||
int dst_y,
|
int dst_y,
|
||||||
int level)
|
int level)
|
||||||
{
|
{
|
||||||
CoglContext *ctx = COGL_TEXTURE (tex_2d)->context;
|
CoglTexture *tex = COGL_TEXTURE (tex_2d);
|
||||||
|
CoglContext *ctx = tex->context;
|
||||||
|
|
||||||
|
/* Assert that the storage for this texture has been allocated */
|
||||||
|
cogl_texture_allocate (tex, NULL); /* (abort on error) */
|
||||||
|
|
||||||
ctx->driver_vtable->texture_2d_copy_from_framebuffer (tex_2d,
|
ctx->driver_vtable->texture_2d_copy_from_framebuffer (tex_2d,
|
||||||
src_x,
|
src_x,
|
||||||
@ -525,7 +524,7 @@ _cogl_texture_2d_get_data (CoglTexture *tex,
|
|||||||
static CoglPixelFormat
|
static CoglPixelFormat
|
||||||
_cogl_texture_2d_get_format (CoglTexture *tex)
|
_cogl_texture_2d_get_format (CoglTexture *tex)
|
||||||
{
|
{
|
||||||
return COGL_TEXTURE_2D (tex)->format;
|
return COGL_TEXTURE_2D (tex)->internal_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLenum
|
static GLenum
|
||||||
@ -550,6 +549,7 @@ static const CoglTextureVtable
|
|||||||
cogl_texture_2d_vtable =
|
cogl_texture_2d_vtable =
|
||||||
{
|
{
|
||||||
TRUE, /* primitive */
|
TRUE, /* primitive */
|
||||||
|
_cogl_texture_2d_allocate,
|
||||||
_cogl_texture_2d_set_region,
|
_cogl_texture_2d_set_region,
|
||||||
_cogl_texture_2d_get_data,
|
_cogl_texture_2d_get_data,
|
||||||
NULL, /* foreach_sub_texture_in_region */
|
NULL, /* foreach_sub_texture_in_region */
|
||||||
|
@ -74,7 +74,6 @@ cogl_is_texture_2d (void *object);
|
|||||||
* @width: Width of the texture to allocate
|
* @width: Width of the texture to allocate
|
||||||
* @height: Height of the texture to allocate
|
* @height: Height of the texture to allocate
|
||||||
* @internal_format: The format of the texture
|
* @internal_format: The format of the texture
|
||||||
* @error: A #CoglError for exceptions
|
|
||||||
*
|
*
|
||||||
* Allocates a low-level #CoglTexture2D texture that your GPU can
|
* Allocates a low-level #CoglTexture2D texture that your GPU can
|
||||||
* texture from directly. This is unlike sliced textures for example
|
* texture from directly. This is unlike sliced textures for example
|
||||||
@ -82,15 +81,18 @@ cogl_is_texture_2d (void *object);
|
|||||||
* textures where Cogl has to modify texture coordinates before they
|
* textures where Cogl has to modify texture coordinates before they
|
||||||
* may be used by the GPU.
|
* may be used by the GPU.
|
||||||
*
|
*
|
||||||
|
* 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 preferably let Cogl
|
||||||
|
* automatically allocate storage lazily when it may know more about
|
||||||
|
* how the texture is being used and can optimize how it is allocated.
|
||||||
|
*
|
||||||
* <note>Many GPUs only support power of two sizes for #CoglTexture2D
|
* <note>Many GPUs only support power of two sizes for #CoglTexture2D
|
||||||
* textures. You can check support for non power of two textures by
|
* textures. You can check support for non power of two textures by
|
||||||
* checking for the %COGL_FEATURE_ID_TEXTURE_NPOT feature via
|
* checking for the %COGL_FEATURE_ID_TEXTURE_NPOT feature via
|
||||||
* cogl_has_feature().</note>
|
* cogl_has_feature().</note>
|
||||||
*
|
*
|
||||||
* Returns: A newly allocated #CoglTexture2D, or if the size is not
|
* Returns: A new #CoglTexture2D object with no storage yet allocated.
|
||||||
* supported (because it is too large or a non-power-of-two
|
|
||||||
* size that the hardware doesn't support) it will return
|
|
||||||
* %NULL and set @error.
|
|
||||||
*
|
*
|
||||||
* Since: 2.0
|
* Since: 2.0
|
||||||
*/
|
*/
|
||||||
@ -98,8 +100,7 @@ CoglTexture2D *
|
|||||||
cogl_texture_2d_new_with_size (CoglContext *ctx,
|
cogl_texture_2d_new_with_size (CoglContext *ctx,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
CoglPixelFormat internal_format,
|
CoglPixelFormat internal_format);
|
||||||
CoglError **error);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cogl_texture_2d_new_from_data:
|
* cogl_texture_2d_new_from_data:
|
||||||
|
@ -36,7 +36,7 @@ struct _CoglTexture3D
|
|||||||
|
|
||||||
/* The internal format of the texture represented as a
|
/* The internal format of the texture represented as a
|
||||||
CoglPixelFormat */
|
CoglPixelFormat */
|
||||||
CoglPixelFormat format;
|
CoglPixelFormat internal_format;
|
||||||
int depth;
|
int depth;
|
||||||
CoglBool auto_mipmap;
|
CoglBool auto_mipmap;
|
||||||
CoglBool mipmaps_dirty;
|
CoglBool mipmaps_dirty;
|
||||||
|
@ -95,7 +95,8 @@ _cogl_texture_3d_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex,
|
|||||||
static void
|
static void
|
||||||
_cogl_texture_3d_free (CoglTexture3D *tex_3d)
|
_cogl_texture_3d_free (CoglTexture3D *tex_3d)
|
||||||
{
|
{
|
||||||
_cogl_delete_gl_texture (tex_3d->gl_texture);
|
if (tex_3d->gl_texture)
|
||||||
|
_cogl_delete_gl_texture (tex_3d->gl_texture);
|
||||||
|
|
||||||
/* Chain up */
|
/* Chain up */
|
||||||
_cogl_texture_free (COGL_TEXTURE (tex_3d));
|
_cogl_texture_free (COGL_TEXTURE (tex_3d));
|
||||||
@ -122,6 +123,8 @@ _cogl_texture_3d_create_base (CoglContext *ctx,
|
|||||||
|
|
||||||
_cogl_texture_init (tex, ctx, width, height, &cogl_texture_3d_vtable);
|
_cogl_texture_init (tex, ctx, width, height, &cogl_texture_3d_vtable);
|
||||||
|
|
||||||
|
tex_3d->gl_texture = 0;
|
||||||
|
|
||||||
tex_3d->depth = depth;
|
tex_3d->depth = depth;
|
||||||
tex_3d->mipmaps_dirty = TRUE;
|
tex_3d->mipmaps_dirty = TRUE;
|
||||||
tex_3d->auto_mipmap = TRUE;
|
tex_3d->auto_mipmap = TRUE;
|
||||||
@ -135,7 +138,7 @@ _cogl_texture_3d_create_base (CoglContext *ctx,
|
|||||||
tex_3d->gl_legacy_texobj_wrap_mode_t = GL_FALSE;
|
tex_3d->gl_legacy_texobj_wrap_mode_t = GL_FALSE;
|
||||||
tex_3d->gl_legacy_texobj_wrap_mode_p = GL_FALSE;
|
tex_3d->gl_legacy_texobj_wrap_mode_p = GL_FALSE;
|
||||||
|
|
||||||
tex_3d->format = internal_format;
|
tex_3d->internal_format = internal_format;
|
||||||
|
|
||||||
return _cogl_texture_3d_object_new (tex_3d);
|
return _cogl_texture_3d_object_new (tex_3d);
|
||||||
}
|
}
|
||||||
@ -206,54 +209,66 @@ cogl_texture_3d_new_with_size (CoglContext *ctx,
|
|||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int depth,
|
int depth,
|
||||||
CoglPixelFormat internal_format,
|
CoglPixelFormat internal_format)
|
||||||
CoglError **error)
|
|
||||||
{
|
{
|
||||||
CoglTexture3D *tex_3d;
|
|
||||||
GLenum gl_intformat;
|
|
||||||
GLenum gl_format;
|
|
||||||
GLenum gl_type;
|
|
||||||
GLenum gl_error;
|
|
||||||
|
|
||||||
/* Since no data, we need some internal format */
|
/* Since no data, we need some internal format */
|
||||||
if (internal_format == COGL_PIXEL_FORMAT_ANY)
|
if (internal_format == COGL_PIXEL_FORMAT_ANY)
|
||||||
internal_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE;
|
internal_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE;
|
||||||
|
|
||||||
|
return _cogl_texture_3d_create_base (ctx,
|
||||||
|
width, height, depth,
|
||||||
|
internal_format);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CoglBool
|
||||||
|
_cogl_texture_3d_allocate (CoglTexture *tex,
|
||||||
|
CoglError **error)
|
||||||
|
{
|
||||||
|
CoglContext *ctx = tex->context;
|
||||||
|
CoglTexture3D *tex_3d = COGL_TEXTURE_3D (tex);
|
||||||
|
GLenum gl_intformat;
|
||||||
|
GLenum gl_format;
|
||||||
|
GLenum gl_type;
|
||||||
|
GLenum gl_error;
|
||||||
|
GLenum gl_texture;
|
||||||
|
|
||||||
if (!_cogl_texture_3d_can_create (ctx,
|
if (!_cogl_texture_3d_can_create (ctx,
|
||||||
width, height, depth,
|
tex->width,
|
||||||
internal_format,
|
tex->height,
|
||||||
|
tex_3d->depth,
|
||||||
|
tex_3d->internal_format,
|
||||||
error))
|
error))
|
||||||
return NULL;
|
return FALSE;
|
||||||
|
|
||||||
internal_format = ctx->driver_vtable->pixel_format_to_gl (ctx,
|
ctx->driver_vtable->pixel_format_to_gl (ctx,
|
||||||
internal_format,
|
tex_3d->internal_format,
|
||||||
&gl_intformat,
|
&gl_intformat,
|
||||||
&gl_format,
|
&gl_format,
|
||||||
&gl_type);
|
&gl_type);
|
||||||
|
|
||||||
tex_3d = _cogl_texture_3d_create_base (ctx,
|
gl_texture =
|
||||||
width, height, depth,
|
ctx->texture_driver->gen (ctx, GL_TEXTURE_3D, tex_3d->internal_format);
|
||||||
internal_format);
|
|
||||||
|
|
||||||
tex_3d->gl_texture =
|
|
||||||
ctx->texture_driver->gen (ctx, GL_TEXTURE_3D, internal_format);
|
|
||||||
_cogl_bind_gl_texture_transient (GL_TEXTURE_3D,
|
_cogl_bind_gl_texture_transient (GL_TEXTURE_3D,
|
||||||
tex_3d->gl_texture,
|
gl_texture,
|
||||||
FALSE);
|
FALSE);
|
||||||
/* Clear any GL errors */
|
/* Clear any GL errors */
|
||||||
while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR)
|
while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR)
|
||||||
;
|
;
|
||||||
|
|
||||||
ctx->glTexImage3D (GL_TEXTURE_3D, 0, gl_intformat,
|
ctx->glTexImage3D (GL_TEXTURE_3D, 0, gl_intformat,
|
||||||
width, height, depth, 0, gl_format, gl_type, NULL);
|
tex->width, tex->height, tex_3d->depth,
|
||||||
|
0, gl_format, gl_type, NULL);
|
||||||
|
|
||||||
if (_cogl_gl_util_catch_out_of_memory (ctx, error))
|
if (_cogl_gl_util_catch_out_of_memory (ctx, error))
|
||||||
{
|
{
|
||||||
cogl_object_unref (tex_3d);
|
GE( ctx, glDeleteTextures (1, &gl_texture) );
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return tex_3d;
|
tex_3d->gl_texture = gl_texture;
|
||||||
|
tex_3d->gl_format = gl_intformat;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
CoglTexture3D *
|
CoglTexture3D *
|
||||||
@ -354,6 +369,8 @@ cogl_texture_3d_new_from_bitmap (CoglBitmap *bmp,
|
|||||||
|
|
||||||
cogl_object_unref (dst_bmp);
|
cogl_object_unref (dst_bmp);
|
||||||
|
|
||||||
|
_cogl_texture_set_allocated (COGL_TEXTURE (tex_3d), TRUE);
|
||||||
|
|
||||||
return tex_3d;
|
return tex_3d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -628,7 +645,7 @@ _cogl_texture_3d_get_data (CoglTexture *tex,
|
|||||||
static CoglPixelFormat
|
static CoglPixelFormat
|
||||||
_cogl_texture_3d_get_format (CoglTexture *tex)
|
_cogl_texture_3d_get_format (CoglTexture *tex)
|
||||||
{
|
{
|
||||||
return COGL_TEXTURE_3D (tex)->format;
|
return COGL_TEXTURE_3D (tex)->internal_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLenum
|
static GLenum
|
||||||
@ -647,6 +664,7 @@ static const CoglTextureVtable
|
|||||||
cogl_texture_3d_vtable =
|
cogl_texture_3d_vtable =
|
||||||
{
|
{
|
||||||
TRUE, /* primitive */
|
TRUE, /* primitive */
|
||||||
|
_cogl_texture_3d_allocate,
|
||||||
_cogl_texture_3d_set_region,
|
_cogl_texture_3d_set_region,
|
||||||
_cogl_texture_3d_get_data,
|
_cogl_texture_3d_get_data,
|
||||||
NULL, /* foreach_sub_texture_in_region */
|
NULL, /* foreach_sub_texture_in_region */
|
||||||
|
@ -55,18 +55,23 @@ typedef struct _CoglTexture3D CoglTexture3D;
|
|||||||
* @depth: depth of the texture in pixels.
|
* @depth: depth of the texture in pixels.
|
||||||
* @internal_format: the #CoglPixelFormat to use for the GPU
|
* @internal_format: the #CoglPixelFormat to use for the GPU
|
||||||
* storage of the texture.
|
* storage of the texture.
|
||||||
* @error: A CoglError return location.
|
|
||||||
*
|
*
|
||||||
* Creates a new Cogl 3D texture with the specified dimensions and
|
* Creates a new #CoglTexture3D texture with the specified dimensions
|
||||||
* pixel format.
|
* and pixel format.
|
||||||
*
|
*
|
||||||
* Note that this function will throw a #CoglError if
|
* The storage for the texture is not allocated before this function
|
||||||
* %COGL_FEATURE_ID_TEXTURE_3D is not advertised. It can also fail if the
|
* returns. You can call cogl_texture_allocate() to explicitly
|
||||||
* requested dimensions are not supported by the GPU.
|
* allocate the underlying storage or preferably let Cogl
|
||||||
|
* automatically allocate storage lazily when it may know more about
|
||||||
|
* how the texture is going to be used and can optimize how it is
|
||||||
|
* allocated.
|
||||||
*
|
*
|
||||||
* Return value: a new #CoglTexture3D object or
|
* <note>This texture will fail to allocate later if
|
||||||
* %NULL on failure and an exception will be returned
|
* %COGL_FEATURE_ID_TEXTURE_3D is not advertised. Allocation can also
|
||||||
* in @error.
|
* fail if the requested dimensions are not supported by the
|
||||||
|
* GPU.</note>
|
||||||
|
*
|
||||||
|
* Returns: A new #CoglTexture3D object with no storage yet allocated.
|
||||||
* Since: 1.10
|
* Since: 1.10
|
||||||
* Stability: Unstable
|
* Stability: Unstable
|
||||||
*/
|
*/
|
||||||
@ -75,8 +80,7 @@ cogl_texture_3d_new_with_size (CoglContext *context,
|
|||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int depth,
|
int depth,
|
||||||
CoglPixelFormat internal_format,
|
CoglPixelFormat internal_format);
|
||||||
CoglError **error);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cogl_texture_3d_new_from_data:
|
* cogl_texture_3d_new_from_data:
|
||||||
|
@ -60,6 +60,9 @@ struct _CoglTextureVtable
|
|||||||
|
|
||||||
CoglBool is_primitive;
|
CoglBool is_primitive;
|
||||||
|
|
||||||
|
CoglBool (* allocate) (CoglTexture *tex,
|
||||||
|
CoglError **error);
|
||||||
|
|
||||||
/* This should update the specified sub region of the texture with a
|
/* This should update the specified sub region of the texture with a
|
||||||
sub region of the given bitmap. The bitmap is not converted
|
sub region of the given bitmap. The bitmap is not converted
|
||||||
before being passed so the implementation is expected to call
|
before being passed so the implementation is expected to call
|
||||||
@ -144,6 +147,7 @@ struct _CoglTexture
|
|||||||
int max_level;
|
int max_level;
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
|
CoglBool allocated;
|
||||||
const CoglTextureVtable *vtable;
|
const CoglTextureVtable *vtable;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -321,4 +325,8 @@ _cogl_texture_get_level_size (CoglTexture *texture,
|
|||||||
int *height,
|
int *height,
|
||||||
int *depth);
|
int *depth);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_texture_set_allocated (CoglTexture *texture,
|
||||||
|
CoglBool allocated);
|
||||||
|
|
||||||
#endif /* __COGL_TEXTURE_PRIVATE_H */
|
#endif /* __COGL_TEXTURE_PRIVATE_H */
|
||||||
|
@ -34,7 +34,7 @@ struct _CoglTextureRectangle
|
|||||||
|
|
||||||
/* The internal format of the texture represented as a
|
/* The internal format of the texture represented as a
|
||||||
CoglPixelFormat */
|
CoglPixelFormat */
|
||||||
CoglPixelFormat format;
|
CoglPixelFormat internal_format;
|
||||||
|
|
||||||
/* TODO: factor out these OpenGL specific members into some form
|
/* TODO: factor out these OpenGL specific members into some form
|
||||||
* of driver private state. */
|
* of driver private state. */
|
||||||
|
@ -102,7 +102,7 @@ _cogl_texture_rectangle_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex,
|
|||||||
static void
|
static void
|
||||||
_cogl_texture_rectangle_free (CoglTextureRectangle *tex_rect)
|
_cogl_texture_rectangle_free (CoglTextureRectangle *tex_rect)
|
||||||
{
|
{
|
||||||
if (!tex_rect->is_foreign)
|
if (!tex_rect->is_foreign && tex_rect->gl_texture)
|
||||||
_cogl_delete_gl_texture (tex_rect->gl_texture);
|
_cogl_delete_gl_texture (tex_rect->gl_texture);
|
||||||
|
|
||||||
/* Chain up */
|
/* Chain up */
|
||||||
@ -173,6 +173,8 @@ _cogl_texture_rectangle_create_base (CoglContext *ctx,
|
|||||||
|
|
||||||
_cogl_texture_init (tex, ctx, width, height, &cogl_texture_rectangle_vtable);
|
_cogl_texture_init (tex, ctx, width, height, &cogl_texture_rectangle_vtable);
|
||||||
|
|
||||||
|
tex_rect->gl_texture = 0;
|
||||||
|
|
||||||
/* We default to GL_LINEAR for both filters */
|
/* We default to GL_LINEAR for both filters */
|
||||||
tex_rect->gl_legacy_texobj_min_filter = GL_LINEAR;
|
tex_rect->gl_legacy_texobj_min_filter = GL_LINEAR;
|
||||||
tex_rect->gl_legacy_texobj_mag_filter = GL_LINEAR;
|
tex_rect->gl_legacy_texobj_mag_filter = GL_LINEAR;
|
||||||
@ -181,7 +183,7 @@ _cogl_texture_rectangle_create_base (CoglContext *ctx,
|
|||||||
tex_rect->gl_legacy_texobj_wrap_mode_s = GL_FALSE;
|
tex_rect->gl_legacy_texobj_wrap_mode_s = GL_FALSE;
|
||||||
tex_rect->gl_legacy_texobj_wrap_mode_t = GL_FALSE;
|
tex_rect->gl_legacy_texobj_wrap_mode_t = GL_FALSE;
|
||||||
|
|
||||||
tex_rect->format = internal_format;
|
tex_rect->internal_format = internal_format;
|
||||||
|
|
||||||
return _cogl_texture_rectangle_object_new (tex_rect);
|
return _cogl_texture_rectangle_object_new (tex_rect);
|
||||||
}
|
}
|
||||||
@ -194,36 +196,59 @@ cogl_texture_rectangle_new_with_size (CoglContext *ctx,
|
|||||||
CoglError **error)
|
CoglError **error)
|
||||||
{
|
{
|
||||||
CoglTextureRectangle *tex_rect;
|
CoglTextureRectangle *tex_rect;
|
||||||
GLenum gl_intformat;
|
|
||||||
GLenum gl_format;
|
|
||||||
GLenum gl_type;
|
|
||||||
GLenum gl_error;
|
|
||||||
|
|
||||||
/* Since no data, we need some internal format */
|
/* Since no data, we need some internal format */
|
||||||
if (internal_format == COGL_PIXEL_FORMAT_ANY)
|
if (internal_format == COGL_PIXEL_FORMAT_ANY)
|
||||||
internal_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE;
|
internal_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE;
|
||||||
|
|
||||||
|
tex_rect =_cogl_texture_rectangle_create_base (ctx,
|
||||||
|
width, height,
|
||||||
|
internal_format);
|
||||||
|
|
||||||
|
/* XXX: This api has been changed for Cogl 2.0 on the master branch
|
||||||
|
* to not take a CoglError to allow the storage to be allocated
|
||||||
|
* lazily but since Mutter uses this api we are currently
|
||||||
|
* maintaining the semantics of immediately allocating the storage
|
||||||
|
*/
|
||||||
|
if (!cogl_texture_allocate (COGL_TEXTURE (tex_rect), error))
|
||||||
|
{
|
||||||
|
cogl_object_unref (tex_rect);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return tex_rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CoglBool
|
||||||
|
_cogl_texture_rectangle_allocate (CoglTexture *tex,
|
||||||
|
CoglError **error)
|
||||||
|
{
|
||||||
|
CoglContext *ctx = tex->context;
|
||||||
|
CoglTextureRectangle *tex_rect = COGL_TEXTURE_RECTANGLE (tex);
|
||||||
|
GLenum gl_intformat;
|
||||||
|
GLenum gl_format;
|
||||||
|
GLenum gl_type;
|
||||||
|
GLenum gl_error;
|
||||||
|
GLenum gl_texture;
|
||||||
|
|
||||||
if (!_cogl_texture_rectangle_can_create (ctx,
|
if (!_cogl_texture_rectangle_can_create (ctx,
|
||||||
width, height,
|
tex->width,
|
||||||
internal_format, error))
|
tex->height,
|
||||||
return NULL;
|
tex_rect->internal_format,
|
||||||
|
error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
internal_format = ctx->driver_vtable->pixel_format_to_gl (ctx,
|
ctx->driver_vtable->pixel_format_to_gl (ctx,
|
||||||
internal_format,
|
tex_rect->internal_format,
|
||||||
&gl_intformat,
|
&gl_intformat,
|
||||||
&gl_format,
|
&gl_format,
|
||||||
&gl_type);
|
&gl_type);
|
||||||
|
|
||||||
tex_rect = _cogl_texture_rectangle_create_base (ctx,
|
gl_texture =
|
||||||
width, height,
|
|
||||||
internal_format);
|
|
||||||
|
|
||||||
tex_rect->gl_texture =
|
|
||||||
ctx->texture_driver->gen (ctx,
|
ctx->texture_driver->gen (ctx,
|
||||||
GL_TEXTURE_RECTANGLE_ARB,
|
GL_TEXTURE_RECTANGLE_ARB,
|
||||||
internal_format);
|
tex_rect->internal_format);
|
||||||
_cogl_bind_gl_texture_transient (GL_TEXTURE_RECTANGLE_ARB,
|
_cogl_bind_gl_texture_transient (GL_TEXTURE_RECTANGLE_ARB,
|
||||||
tex_rect->gl_texture,
|
gl_texture,
|
||||||
tex_rect->is_foreign);
|
tex_rect->is_foreign);
|
||||||
|
|
||||||
/* Clear any GL errors */
|
/* Clear any GL errors */
|
||||||
@ -231,15 +256,18 @@ cogl_texture_rectangle_new_with_size (CoglContext *ctx,
|
|||||||
;
|
;
|
||||||
|
|
||||||
ctx->glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, gl_intformat,
|
ctx->glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, gl_intformat,
|
||||||
width, height, 0, gl_format, gl_type, NULL);
|
tex->width, tex->height, 0, gl_format, gl_type, NULL);
|
||||||
|
|
||||||
if (_cogl_gl_util_catch_out_of_memory (ctx, error))
|
if (_cogl_gl_util_catch_out_of_memory (ctx, error))
|
||||||
{
|
{
|
||||||
cogl_object_unref (tex_rect);
|
GE( ctx, glDeleteTextures (1, &gl_texture) );
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return tex_rect;
|
tex_rect->gl_texture = gl_texture;
|
||||||
|
tex_rect->gl_format = gl_intformat;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
CoglTextureRectangle *
|
CoglTextureRectangle *
|
||||||
@ -308,6 +336,8 @@ cogl_texture_rectangle_new_from_bitmap (CoglBitmap *bmp,
|
|||||||
|
|
||||||
cogl_object_unref (dst_bmp);
|
cogl_object_unref (dst_bmp);
|
||||||
|
|
||||||
|
_cogl_texture_set_allocated (COGL_TEXTURE (tex_rect), TRUE);
|
||||||
|
|
||||||
return tex_rect;
|
return tex_rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -424,7 +454,7 @@ cogl_texture_rectangle_new_from_foreign (CoglContext *ctx,
|
|||||||
/* Setup bitmap info */
|
/* Setup bitmap info */
|
||||||
tex_rect->is_foreign = TRUE;
|
tex_rect->is_foreign = TRUE;
|
||||||
|
|
||||||
tex_rect->format = format;
|
tex_rect->internal_format = format;
|
||||||
|
|
||||||
tex_rect->gl_texture = gl_handle;
|
tex_rect->gl_texture = gl_handle;
|
||||||
tex_rect->gl_format = gl_int_format;
|
tex_rect->gl_format = gl_int_format;
|
||||||
@ -433,6 +463,8 @@ cogl_texture_rectangle_new_from_foreign (CoglContext *ctx,
|
|||||||
tex_rect->gl_legacy_texobj_min_filter = GL_FALSE;
|
tex_rect->gl_legacy_texobj_min_filter = GL_FALSE;
|
||||||
tex_rect->gl_legacy_texobj_mag_filter = GL_FALSE;
|
tex_rect->gl_legacy_texobj_mag_filter = GL_FALSE;
|
||||||
|
|
||||||
|
_cogl_texture_set_allocated (COGL_TEXTURE (tex_rect), TRUE);
|
||||||
|
|
||||||
return tex_rect;
|
return tex_rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -624,7 +656,7 @@ _cogl_texture_rectangle_get_data (CoglTexture *tex,
|
|||||||
static CoglPixelFormat
|
static CoglPixelFormat
|
||||||
_cogl_texture_rectangle_get_format (CoglTexture *tex)
|
_cogl_texture_rectangle_get_format (CoglTexture *tex)
|
||||||
{
|
{
|
||||||
return COGL_TEXTURE_RECTANGLE (tex)->format;
|
return COGL_TEXTURE_RECTANGLE (tex)->internal_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLenum
|
static GLenum
|
||||||
@ -649,6 +681,7 @@ static const CoglTextureVtable
|
|||||||
cogl_texture_rectangle_vtable =
|
cogl_texture_rectangle_vtable =
|
||||||
{
|
{
|
||||||
TRUE, /* primitive */
|
TRUE, /* primitive */
|
||||||
|
_cogl_texture_rectangle_allocate,
|
||||||
_cogl_texture_rectangle_set_region,
|
_cogl_texture_rectangle_set_region,
|
||||||
_cogl_texture_rectangle_get_data,
|
_cogl_texture_rectangle_get_data,
|
||||||
NULL, /* foreach_sub_texture_in_region */
|
NULL, /* foreach_sub_texture_in_region */
|
||||||
|
@ -139,6 +139,7 @@ _cogl_texture_init (CoglTexture *texture,
|
|||||||
texture->max_level = 0;
|
texture->max_level = 0;
|
||||||
texture->width = width;
|
texture->width = width;
|
||||||
texture->height = height;
|
texture->height = height;
|
||||||
|
texture->allocated = FALSE;
|
||||||
texture->vtable = vtable;
|
texture->vtable = vtable;
|
||||||
texture->framebuffers = NULL;
|
texture->framebuffers = NULL;
|
||||||
}
|
}
|
||||||
@ -440,6 +441,20 @@ _cogl_texture_get_type (CoglTexture *texture)
|
|||||||
void
|
void
|
||||||
_cogl_texture_pre_paint (CoglTexture *texture, CoglTexturePrePaintFlags flags)
|
_cogl_texture_pre_paint (CoglTexture *texture, CoglTexturePrePaintFlags flags)
|
||||||
{
|
{
|
||||||
|
/* Assert that the storage for the texture exists already if we're
|
||||||
|
* about to reference it for painting.
|
||||||
|
*
|
||||||
|
* Note: we abort on error here since it's a bit late to do anything
|
||||||
|
* about it if we fail to allocate the texture and the app could
|
||||||
|
* have explicitly allocated the texture earlier to handle problems
|
||||||
|
* gracefully.
|
||||||
|
*
|
||||||
|
* XXX: Maybe it could even be considered a programmer error if the
|
||||||
|
* texture hasn't been allocated by this point since it implies we
|
||||||
|
* are abount to paint with undefined texture contents?
|
||||||
|
*/
|
||||||
|
cogl_texture_allocate (texture, NULL);
|
||||||
|
|
||||||
texture->vtable->pre_paint (texture, flags);
|
texture->vtable->pre_paint (texture, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,10 +480,12 @@ _cogl_texture_set_region_from_bitmap (CoglTexture *texture,
|
|||||||
>= width, FALSE);
|
>= width, FALSE);
|
||||||
_COGL_RETURN_VAL_IF_FAIL ((cogl_bitmap_get_height (bmp) - src_y)
|
_COGL_RETURN_VAL_IF_FAIL ((cogl_bitmap_get_height (bmp) - src_y)
|
||||||
>= height, FALSE);
|
>= height, FALSE);
|
||||||
|
_COGL_RETURN_VAL_IF_FAIL (width > 0, FALSE);
|
||||||
|
_COGL_RETURN_VAL_IF_FAIL (height > 0, FALSE);
|
||||||
|
|
||||||
/* Shortcut out early if the image is empty */
|
/* Assert that the storage for this texture has been allocated */
|
||||||
if (width == 0 || height == 0)
|
if (!cogl_texture_allocate (texture, error))
|
||||||
return TRUE;
|
return FALSE;
|
||||||
|
|
||||||
/* Note that we don't prepare the bitmap for upload here because
|
/* Note that we don't prepare the bitmap for upload here because
|
||||||
some backends may be internally using a different format for the
|
some backends may be internally using a different format for the
|
||||||
@ -897,10 +914,12 @@ get_texture_bits_via_offscreen (CoglTexture *texture,
|
|||||||
COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL,
|
COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
if (offscreen == NULL)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
framebuffer = COGL_FRAMEBUFFER (offscreen);
|
framebuffer = COGL_FRAMEBUFFER (offscreen);
|
||||||
|
if (!cogl_framebuffer_allocate (framebuffer, &ignore_error))
|
||||||
|
{
|
||||||
|
cogl_error_free (ignore_error);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
bitmap = cogl_bitmap_new_for_data (ctx,
|
bitmap = cogl_bitmap_new_for_data (ctx,
|
||||||
width, height,
|
width, height,
|
||||||
@ -1390,3 +1409,22 @@ _cogl_texture_spans_foreach_in_region (CoglSpan *x_spans,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_texture_set_allocated (CoglTexture *texture,
|
||||||
|
CoglBool allocated)
|
||||||
|
{
|
||||||
|
texture->allocated = allocated;
|
||||||
|
}
|
||||||
|
|
||||||
|
CoglBool
|
||||||
|
cogl_texture_allocate (CoglTexture *texture,
|
||||||
|
CoglError **error)
|
||||||
|
{
|
||||||
|
if (texture->allocated)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
texture->allocated = texture->vtable->allocate (texture, error);
|
||||||
|
|
||||||
|
return texture->allocated;
|
||||||
|
}
|
||||||
|
@ -112,7 +112,14 @@ uint32_t cogl_texture_error_quark (void);
|
|||||||
*
|
*
|
||||||
* Creates a new #CoglTexture with the specified dimensions and pixel format.
|
* Creates a new #CoglTexture with the specified dimensions and pixel format.
|
||||||
*
|
*
|
||||||
* Return value: A newly created #CoglTexture or %NULL on failure
|
* The storage for the texture is not necesarily created before this
|
||||||
|
* function returns. The storage can be explicitly allocated using
|
||||||
|
* cogl_texture_allocate() or preferably you can let Cogl
|
||||||
|
* automatically allocate the storage lazily when uploading data when
|
||||||
|
* Cogl may know more about how the texture will be used and can
|
||||||
|
* optimize how it is allocated.
|
||||||
|
*
|
||||||
|
* Return value: A newly created #CoglTexture
|
||||||
*
|
*
|
||||||
* Since: 0.8
|
* Since: 0.8
|
||||||
*/
|
*/
|
||||||
@ -517,6 +524,28 @@ cogl_texture_unref (void *texture) G_GNUC_DEPRECATED;
|
|||||||
|
|
||||||
#endif /* COGL_DISABLE_DEPRECATED */
|
#endif /* COGL_DISABLE_DEPRECATED */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_texture_allocate:
|
||||||
|
* @texture: A #CoglTexture
|
||||||
|
* @error: A #CoglError to return exceptional errors or %NULL
|
||||||
|
*
|
||||||
|
* Explicitly allocates the storage for the given @texture which
|
||||||
|
* allows you to be sure that there is enough memory for the
|
||||||
|
* texture and if not then the error can be handled gracefully.
|
||||||
|
*
|
||||||
|
* <note>Normally applications don't need to use this api directly
|
||||||
|
* since the texture will be implicitly allocated when data is set on
|
||||||
|
* the texture, or if the texture is attached to a #CoglOffscreen
|
||||||
|
* framebuffer and rendered too.</note>
|
||||||
|
*
|
||||||
|
* Return value: %TRUE if the texture was successfully allocated,
|
||||||
|
* otherwise %FALSE and @error will be updated if it
|
||||||
|
* wasn't %NULL.
|
||||||
|
*/
|
||||||
|
CoglBool
|
||||||
|
cogl_texture_allocate (CoglTexture *texture,
|
||||||
|
CoglError **error);
|
||||||
|
|
||||||
COGL_END_DECLS
|
COGL_END_DECLS
|
||||||
|
|
||||||
#endif /* __COGL_TEXTURE_H__ */
|
#endif /* __COGL_TEXTURE_H__ */
|
||||||
|
@ -382,8 +382,7 @@ create_depth_texture (CoglContext *ctx,
|
|||||||
|
|
||||||
depth_texture = cogl_texture_2d_new_with_size (ctx,
|
depth_texture = cogl_texture_2d_new_with_size (ctx,
|
||||||
width, height,
|
width, height,
|
||||||
format,
|
format);
|
||||||
NULL);
|
|
||||||
|
|
||||||
return COGL_TEXTURE (depth_texture);
|
return COGL_TEXTURE (depth_texture);
|
||||||
}
|
}
|
||||||
@ -712,14 +711,14 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
|
|||||||
offscreen->texture_level_width,
|
offscreen->texture_level_width,
|
||||||
offscreen->texture_level_height);
|
offscreen->texture_level_height);
|
||||||
|
|
||||||
if (offscreen->depth_texture)
|
if (!cogl_texture_allocate (offscreen->depth_texture, error))
|
||||||
_cogl_texture_associate_framebuffer (offscreen->depth_texture, fb);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
_cogl_set_error (error, COGL_FRAMEBUFFER_ERROR,
|
cogl_object_unref (offscreen->depth_texture);
|
||||||
COGL_FRAMEBUFFER_ERROR_ALLOCATE,
|
offscreen->depth_texture = NULL;
|
||||||
"Failed to allocate depth texture for framebuffer");
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_cogl_texture_associate_framebuffer (offscreen->depth_texture, fb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: The framebuffer_object spec isn't clear in defining whether attaching
|
/* XXX: The framebuffer_object spec isn't clear in defining whether attaching
|
||||||
|
@ -44,12 +44,9 @@ _cogl_texture_2d_gl_can_create (CoglContext *ctx,
|
|||||||
void
|
void
|
||||||
_cogl_texture_2d_gl_init (CoglTexture2D *tex_2d);
|
_cogl_texture_2d_gl_init (CoglTexture2D *tex_2d);
|
||||||
|
|
||||||
CoglTexture2D *
|
CoglBool
|
||||||
_cogl_texture_2d_gl_new_with_size (CoglContext *ctx,
|
_cogl_texture_2d_gl_allocate (CoglTexture *tex,
|
||||||
int width,
|
CoglError **error);
|
||||||
int height,
|
|
||||||
CoglPixelFormat internal_format,
|
|
||||||
CoglError **error);
|
|
||||||
|
|
||||||
CoglTexture2D *
|
CoglTexture2D *
|
||||||
_cogl_texture_2d_gl_new_from_bitmap (CoglBitmap *bmp,
|
_cogl_texture_2d_gl_new_from_bitmap (CoglBitmap *bmp,
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
void
|
void
|
||||||
_cogl_texture_2d_gl_free (CoglTexture2D *tex_2d)
|
_cogl_texture_2d_gl_free (CoglTexture2D *tex_2d)
|
||||||
{
|
{
|
||||||
if (!tex_2d->is_foreign)
|
if (!tex_2d->is_foreign && tex_2d->gl_texture)
|
||||||
_cogl_delete_gl_texture (tex_2d->gl_texture);
|
_cogl_delete_gl_texture (tex_2d->gl_texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,6 +79,8 @@ _cogl_texture_2d_gl_can_create (CoglContext *ctx,
|
|||||||
void
|
void
|
||||||
_cogl_texture_2d_gl_init (CoglTexture2D *tex_2d)
|
_cogl_texture_2d_gl_init (CoglTexture2D *tex_2d)
|
||||||
{
|
{
|
||||||
|
tex_2d->gl_texture = 0;
|
||||||
|
|
||||||
/* We default to GL_LINEAR for both filters */
|
/* We default to GL_LINEAR for both filters */
|
||||||
tex_2d->gl_legacy_texobj_min_filter = GL_LINEAR;
|
tex_2d->gl_legacy_texobj_min_filter = GL_LINEAR;
|
||||||
tex_2d->gl_legacy_texobj_mag_filter = GL_LINEAR;
|
tex_2d->gl_legacy_texobj_mag_filter = GL_LINEAR;
|
||||||
@ -88,36 +90,43 @@ _cogl_texture_2d_gl_init (CoglTexture2D *tex_2d)
|
|||||||
tex_2d->gl_legacy_texobj_wrap_mode_t = GL_FALSE;
|
tex_2d->gl_legacy_texobj_wrap_mode_t = GL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
CoglTexture2D *
|
CoglBool
|
||||||
_cogl_texture_2d_gl_new_with_size (CoglContext *ctx,
|
_cogl_texture_2d_gl_allocate (CoglTexture *tex,
|
||||||
int width,
|
CoglError **error)
|
||||||
int height,
|
|
||||||
CoglPixelFormat internal_format,
|
|
||||||
CoglError **error)
|
|
||||||
{
|
{
|
||||||
CoglTexture2D *tex_2d;
|
CoglContext *ctx = tex->context;
|
||||||
|
CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex);
|
||||||
GLenum gl_intformat;
|
GLenum gl_intformat;
|
||||||
GLenum gl_format;
|
GLenum gl_format;
|
||||||
GLenum gl_type;
|
GLenum gl_type;
|
||||||
GLenum gl_error;
|
GLenum gl_error;
|
||||||
|
GLenum gl_texture;
|
||||||
|
|
||||||
internal_format = ctx->driver_vtable->pixel_format_to_gl (ctx,
|
if (!_cogl_texture_2d_gl_can_create (ctx,
|
||||||
internal_format,
|
tex->width,
|
||||||
&gl_intformat,
|
tex->height,
|
||||||
&gl_format,
|
tex_2d->internal_format))
|
||||||
&gl_type);
|
{
|
||||||
|
_cogl_set_error (error, COGL_TEXTURE_ERROR,
|
||||||
|
COGL_TEXTURE_ERROR_SIZE,
|
||||||
|
"Failed to create texture 2d due to size/format"
|
||||||
|
" constraints");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
tex_2d = _cogl_texture_2d_create_base (ctx,
|
ctx->driver_vtable->pixel_format_to_gl (ctx,
|
||||||
width, height,
|
tex_2d->internal_format,
|
||||||
internal_format);
|
&gl_intformat,
|
||||||
|
&gl_format,
|
||||||
|
&gl_type);
|
||||||
|
|
||||||
tex_2d->gl_texture =
|
gl_texture =
|
||||||
ctx->texture_driver->gen (ctx, GL_TEXTURE_2D, internal_format);
|
ctx->texture_driver->gen (ctx, GL_TEXTURE_2D, tex_2d->internal_format);
|
||||||
|
|
||||||
tex_2d->gl_internal_format = gl_intformat;
|
tex_2d->gl_internal_format = gl_intformat;
|
||||||
|
|
||||||
_cogl_bind_gl_texture_transient (GL_TEXTURE_2D,
|
_cogl_bind_gl_texture_transient (GL_TEXTURE_2D,
|
||||||
tex_2d->gl_texture,
|
gl_texture,
|
||||||
tex_2d->is_foreign);
|
tex_2d->is_foreign);
|
||||||
|
|
||||||
/* Clear any GL errors */
|
/* Clear any GL errors */
|
||||||
@ -125,15 +134,18 @@ _cogl_texture_2d_gl_new_with_size (CoglContext *ctx,
|
|||||||
;
|
;
|
||||||
|
|
||||||
ctx->glTexImage2D (GL_TEXTURE_2D, 0, gl_intformat,
|
ctx->glTexImage2D (GL_TEXTURE_2D, 0, gl_intformat,
|
||||||
width, height, 0, gl_format, gl_type, NULL);
|
tex->width, tex->height, 0, gl_format, gl_type, NULL);
|
||||||
|
|
||||||
if (_cogl_gl_util_catch_out_of_memory (ctx, error))
|
if (_cogl_gl_util_catch_out_of_memory (ctx, error))
|
||||||
{
|
{
|
||||||
cogl_object_unref (tex_2d);
|
GE( ctx, glDeleteTextures (1, &gl_texture) );
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return tex_2d;
|
tex_2d->gl_texture = gl_texture;
|
||||||
|
tex_2d->gl_internal_format = gl_intformat;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
CoglTexture2D *
|
CoglTexture2D *
|
||||||
@ -213,6 +225,8 @@ _cogl_texture_2d_gl_new_from_bitmap (CoglBitmap *bmp,
|
|||||||
|
|
||||||
cogl_object_unref (dst_bmp);
|
cogl_object_unref (dst_bmp);
|
||||||
|
|
||||||
|
_cogl_texture_set_allocated (COGL_TEXTURE (tex_2d), TRUE);
|
||||||
|
|
||||||
return tex_2d;
|
return tex_2d;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -249,9 +263,12 @@ _cogl_egl_texture_2d_gl_new_from_image (CoglContext *ctx,
|
|||||||
COGL_TEXTURE_ERROR_BAD_PARAMETER,
|
COGL_TEXTURE_ERROR_BAD_PARAMETER,
|
||||||
"Could not create a CoglTexture2D from a given "
|
"Could not create a CoglTexture2D from a given "
|
||||||
"EGLImage");
|
"EGLImage");
|
||||||
|
cogl_object_unref (tex_2d);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_cogl_texture_set_allocated (COGL_TEXTURE (tex_2d), TRUE);
|
||||||
|
|
||||||
return tex_2d;
|
return tex_2d;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -442,8 +459,6 @@ cogl_texture_2d_new_from_foreign (CoglContext *ctx,
|
|||||||
tex_2d->is_foreign = TRUE;
|
tex_2d->is_foreign = TRUE;
|
||||||
tex_2d->mipmaps_dirty = TRUE;
|
tex_2d->mipmaps_dirty = TRUE;
|
||||||
|
|
||||||
tex_2d->format = format;
|
|
||||||
|
|
||||||
tex_2d->gl_texture = gl_handle;
|
tex_2d->gl_texture = gl_handle;
|
||||||
tex_2d->gl_internal_format = gl_int_format;
|
tex_2d->gl_internal_format = gl_int_format;
|
||||||
|
|
||||||
@ -451,6 +466,8 @@ cogl_texture_2d_new_from_foreign (CoglContext *ctx,
|
|||||||
tex_2d->gl_legacy_texobj_min_filter = GL_FALSE;
|
tex_2d->gl_legacy_texobj_min_filter = GL_FALSE;
|
||||||
tex_2d->gl_legacy_texobj_mag_filter = GL_FALSE;
|
tex_2d->gl_legacy_texobj_mag_filter = GL_FALSE;
|
||||||
|
|
||||||
|
_cogl_texture_set_allocated (COGL_TEXTURE (tex_2d), TRUE);
|
||||||
|
|
||||||
return tex_2d;
|
return tex_2d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,7 +482,8 @@ _cogl_texture_2d_gl_copy_from_framebuffer (CoglTexture2D *tex_2d,
|
|||||||
int dst_y,
|
int dst_y,
|
||||||
int level)
|
int level)
|
||||||
{
|
{
|
||||||
CoglContext *ctx = COGL_TEXTURE (tex_2d)->context;
|
CoglTexture *tex = COGL_TEXTURE (tex_2d);
|
||||||
|
CoglContext *ctx = tex->context;
|
||||||
|
|
||||||
/* Make sure the current framebuffers are bound, though we don't need to
|
/* Make sure the current framebuffers are bound, though we don't need to
|
||||||
* flush the clip state here since we aren't going to draw to the
|
* flush the clip state here since we aren't going to draw to the
|
||||||
|
@ -638,7 +638,7 @@ _cogl_driver_gl =
|
|||||||
_cogl_texture_2d_gl_free,
|
_cogl_texture_2d_gl_free,
|
||||||
_cogl_texture_2d_gl_can_create,
|
_cogl_texture_2d_gl_can_create,
|
||||||
_cogl_texture_2d_gl_init,
|
_cogl_texture_2d_gl_init,
|
||||||
_cogl_texture_2d_gl_new_with_size,
|
_cogl_texture_2d_gl_allocate,
|
||||||
_cogl_texture_2d_gl_new_from_bitmap,
|
_cogl_texture_2d_gl_new_from_bitmap,
|
||||||
#if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base)
|
#if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base)
|
||||||
_cogl_egl_texture_2d_gl_new_from_image,
|
_cogl_egl_texture_2d_gl_new_from_image,
|
||||||
|
@ -380,7 +380,7 @@ _cogl_driver_gles =
|
|||||||
_cogl_texture_2d_gl_free,
|
_cogl_texture_2d_gl_free,
|
||||||
_cogl_texture_2d_gl_can_create,
|
_cogl_texture_2d_gl_can_create,
|
||||||
_cogl_texture_2d_gl_init,
|
_cogl_texture_2d_gl_init,
|
||||||
_cogl_texture_2d_gl_new_with_size,
|
_cogl_texture_2d_gl_allocate,
|
||||||
_cogl_texture_2d_gl_new_from_bitmap,
|
_cogl_texture_2d_gl_new_from_bitmap,
|
||||||
#if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base)
|
#if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base)
|
||||||
_cogl_egl_texture_2d_gl_new_from_image,
|
_cogl_egl_texture_2d_gl_new_from_image,
|
||||||
|
@ -68,7 +68,7 @@ _cogl_driver_nop =
|
|||||||
_cogl_texture_2d_nop_free,
|
_cogl_texture_2d_nop_free,
|
||||||
_cogl_texture_2d_nop_can_create,
|
_cogl_texture_2d_nop_can_create,
|
||||||
_cogl_texture_2d_nop_init,
|
_cogl_texture_2d_nop_init,
|
||||||
_cogl_texture_2d_nop_new_with_size,
|
_cogl_texture_2d_nop_allocate,
|
||||||
_cogl_texture_2d_nop_new_from_bitmap,
|
_cogl_texture_2d_nop_new_from_bitmap,
|
||||||
#if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base)
|
#if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base)
|
||||||
_cogl_egl_texture_2d_nop_new_from_image,
|
_cogl_egl_texture_2d_nop_new_from_image,
|
||||||
|
@ -44,12 +44,9 @@ _cogl_texture_2d_nop_can_create (CoglContext *ctx,
|
|||||||
void
|
void
|
||||||
_cogl_texture_2d_nop_init (CoglTexture2D *tex_2d);
|
_cogl_texture_2d_nop_init (CoglTexture2D *tex_2d);
|
||||||
|
|
||||||
CoglTexture2D *
|
CoglBool
|
||||||
_cogl_texture_2d_nop_new_with_size (CoglContext *ctx,
|
_cogl_texture_2d_nop_allocate (CoglTexture *tex,
|
||||||
int width,
|
CoglError **error);
|
||||||
int height,
|
|
||||||
CoglPixelFormat internal_format,
|
|
||||||
CoglError **error);
|
|
||||||
|
|
||||||
CoglTexture2D *
|
CoglTexture2D *
|
||||||
_cogl_texture_2d_nop_new_from_bitmap (CoglBitmap *bmp,
|
_cogl_texture_2d_nop_new_from_bitmap (CoglBitmap *bmp,
|
||||||
|
@ -55,16 +55,11 @@ _cogl_texture_2d_nop_init (CoglTexture2D *tex_2d)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CoglTexture2D *
|
CoglBool
|
||||||
_cogl_texture_2d_nop_new_with_size (CoglContext *ctx,
|
_cogl_texture_2d_nop_allocate (CoglTexture *tex,
|
||||||
int width,
|
CoglError **error)
|
||||||
int height,
|
|
||||||
CoglPixelFormat internal_format,
|
|
||||||
CoglError **error)
|
|
||||||
{
|
{
|
||||||
return _cogl_texture_2d_create_base (ctx,
|
return TRUE;
|
||||||
width, height,
|
|
||||||
internal_format);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CoglTexture2D *
|
CoglTexture2D *
|
||||||
@ -72,11 +67,10 @@ _cogl_texture_2d_nop_new_from_bitmap (CoglBitmap *bmp,
|
|||||||
CoglPixelFormat internal_format,
|
CoglPixelFormat internal_format,
|
||||||
CoglError **error)
|
CoglError **error)
|
||||||
{
|
{
|
||||||
return _cogl_texture_2d_nop_new_with_size (_cogl_bitmap_get_context (bmp),
|
return _cogl_texture_2d_create_base (_cogl_bitmap_get_context (bmp),
|
||||||
cogl_bitmap_get_width (bmp),
|
cogl_bitmap_get_width (bmp),
|
||||||
cogl_bitmap_get_height (bmp),
|
cogl_bitmap_get_height (bmp),
|
||||||
internal_format,
|
internal_format);
|
||||||
error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base)
|
#if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base)
|
||||||
|
@ -361,9 +361,18 @@ cogl_texture_pixmap_x11_new (CoglContext *ctxt,
|
|||||||
if (!tex_pixmap->use_winsys_texture)
|
if (!tex_pixmap->use_winsys_texture)
|
||||||
tex_pixmap->winsys = NULL;
|
tex_pixmap->winsys = NULL;
|
||||||
|
|
||||||
|
_cogl_texture_set_allocated (tex, TRUE);
|
||||||
|
|
||||||
return _cogl_texture_pixmap_x11_object_new (tex_pixmap);
|
return _cogl_texture_pixmap_x11_object_new (tex_pixmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CoglBool
|
||||||
|
_cogl_texture_pixmap_x11_allocate (CoglTexture *tex,
|
||||||
|
CoglError **error)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Tries to allocate enough shared mem to handle a full size
|
/* Tries to allocate enough shared mem to handle a full size
|
||||||
* update size of the X Pixmap. */
|
* update size of the X Pixmap. */
|
||||||
static void
|
static void
|
||||||
@ -1001,6 +1010,7 @@ static const CoglTextureVtable
|
|||||||
cogl_texture_pixmap_x11_vtable =
|
cogl_texture_pixmap_x11_vtable =
|
||||||
{
|
{
|
||||||
FALSE, /* not primitive */
|
FALSE, /* not primitive */
|
||||||
|
_cogl_texture_pixmap_x11_allocate,
|
||||||
_cogl_texture_pixmap_x11_set_region,
|
_cogl_texture_pixmap_x11_set_region,
|
||||||
_cogl_texture_pixmap_x11_get_data,
|
_cogl_texture_pixmap_x11_get_data,
|
||||||
_cogl_texture_pixmap_x11_foreach_sub_texture_in_region,
|
_cogl_texture_pixmap_x11_foreach_sub_texture_in_region,
|
||||||
|
@ -1980,17 +1980,17 @@ _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
|
|||||||
cogl_texture_2d_new_with_size (ctx,
|
cogl_texture_2d_new_with_size (ctx,
|
||||||
tex->width,
|
tex->width,
|
||||||
tex->height,
|
tex->height,
|
||||||
texture_format,
|
texture_format));
|
||||||
NULL));
|
|
||||||
|
|
||||||
if (glx_tex_pixmap->glx_tex)
|
if (cogl_texture_allocate (glx_tex_pixmap->glx_tex, &error))
|
||||||
COGL_NOTE (TEXTURE_PIXMAP, "Created a texture 2d for %p",
|
COGL_NOTE (TEXTURE_PIXMAP, "Created a texture 2d for %p",
|
||||||
tex_pixmap);
|
tex_pixmap);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
COGL_NOTE (TEXTURE_PIXMAP, "Falling back for %p because a "
|
COGL_NOTE (TEXTURE_PIXMAP, "Falling back for %p because a "
|
||||||
"texture 2d could not be created",
|
"texture 2d could not be created: %s",
|
||||||
tex_pixmap);
|
tex_pixmap, error->message);
|
||||||
|
cogl_error_free (error);
|
||||||
free_glx_pixmap (ctx, glx_tex_pixmap);
|
free_glx_pixmap (ctx, glx_tex_pixmap);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,7 @@ test_push_pop_single_context (void)
|
|||||||
cogl_texture_2d_new_with_size (test_ctx,
|
cogl_texture_2d_new_with_size (test_ctx,
|
||||||
cogl_framebuffer_get_width (test_fb),
|
cogl_framebuffer_get_width (test_fb),
|
||||||
cogl_framebuffer_get_height (test_fb),
|
cogl_framebuffer_get_height (test_fb),
|
||||||
COGL_PIXEL_FORMAT_ANY,
|
COGL_PIXEL_FORMAT_ANY));
|
||||||
NULL));
|
|
||||||
offscreen = cogl_offscreen_new_to_texture (offscreen_texture);
|
offscreen = cogl_offscreen_new_to_texture (offscreen_texture);
|
||||||
|
|
||||||
pipeline = cogl_pipeline_new (test_ctx);
|
pipeline = cogl_pipeline_new (test_ctx);
|
||||||
@ -152,8 +151,7 @@ create_gles2_context (CoglTexture **offscreen_texture,
|
|||||||
cogl_texture_2d_new_with_size (test_ctx,
|
cogl_texture_2d_new_with_size (test_ctx,
|
||||||
cogl_framebuffer_get_width (test_fb),
|
cogl_framebuffer_get_width (test_fb),
|
||||||
cogl_framebuffer_get_height (test_fb),
|
cogl_framebuffer_get_height (test_fb),
|
||||||
COGL_PIXEL_FORMAT_ANY,
|
COGL_PIXEL_FORMAT_ANY));
|
||||||
NULL));
|
|
||||||
*offscreen = cogl_offscreen_new_to_texture (*offscreen_texture);
|
*offscreen = cogl_offscreen_new_to_texture (*offscreen_texture);
|
||||||
|
|
||||||
*pipeline = cogl_pipeline_new (test_ctx);
|
*pipeline = cogl_pipeline_new (test_ctx);
|
||||||
|
@ -45,8 +45,7 @@ test_paint (TestState *state)
|
|||||||
tex_2d = cogl_texture_2d_new_with_size (test_ctx,
|
tex_2d = cogl_texture_2d_new_with_size (test_ctx,
|
||||||
state->fb_width,
|
state->fb_width,
|
||||||
state->fb_height,
|
state->fb_height,
|
||||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
COGL_PIXEL_FORMAT_RGBA_8888_PRE);
|
||||||
NULL);
|
|
||||||
tex = COGL_TEXTURE (tex_2d);
|
tex = COGL_TEXTURE (tex_2d);
|
||||||
|
|
||||||
offscreen = cogl_offscreen_new_to_texture (tex);
|
offscreen = cogl_offscreen_new_to_texture (tex);
|
||||||
@ -127,8 +126,7 @@ test_flush (TestState *state)
|
|||||||
|
|
||||||
tex_2d = cogl_texture_2d_new_with_size (test_ctx,
|
tex_2d = cogl_texture_2d_new_with_size (test_ctx,
|
||||||
16, 16, /* width/height */
|
16, 16, /* width/height */
|
||||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
COGL_PIXEL_FORMAT_RGBA_8888_PRE);
|
||||||
NULL);
|
|
||||||
tex = COGL_TEXTURE (tex_2d);
|
tex = COGL_TEXTURE (tex_2d);
|
||||||
|
|
||||||
offscreen = cogl_offscreen_new_to_texture (tex);
|
offscreen = cogl_offscreen_new_to_texture (tex);
|
||||||
|
@ -122,11 +122,7 @@ test_utils_init (TestFlags requirement_flags,
|
|||||||
CoglOffscreen *offscreen;
|
CoglOffscreen *offscreen;
|
||||||
CoglTexture2D *tex = cogl_texture_2d_new_with_size (test_ctx,
|
CoglTexture2D *tex = cogl_texture_2d_new_with_size (test_ctx,
|
||||||
FB_WIDTH, FB_HEIGHT,
|
FB_WIDTH, FB_HEIGHT,
|
||||||
COGL_PIXEL_FORMAT_ANY,
|
COGL_PIXEL_FORMAT_ANY);
|
||||||
&error);
|
|
||||||
if (!tex)
|
|
||||||
g_critical ("Failed to allocate texture: %s", error->message);
|
|
||||||
|
|
||||||
offscreen = cogl_offscreen_new_to_texture (COGL_TEXTURE (tex));
|
offscreen = cogl_offscreen_new_to_texture (COGL_TEXTURE (tex));
|
||||||
test_fb = COGL_FRAMEBUFFER (offscreen);
|
test_fb = COGL_FRAMEBUFFER (offscreen);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user