mutter/cogl/cogl-texture-2d.c

911 lines
30 KiB
C
Raw Normal View History

/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2009 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*
*
* Authors:
* Neil Roberts <neil@linux.intel.com>
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "cogl-private.h"
#include "cogl-util.h"
#include "cogl-texture-private.h"
#include "cogl-texture-2d-private.h"
#include "cogl-texture-driver.h"
#include "cogl-context-private.h"
#include "cogl-handle.h"
#include "cogl-journal-private.h"
cogl: rename CoglMaterial -> CoglPipeline This applies an API naming change that's been deliberated over for a while now which is to rename CoglMaterial to CoglPipeline. For now the new pipeline API is marked as experimental and public headers continue to talk about materials not pipelines. The CoglMaterial API is now maintained in terms of the cogl_pipeline API internally. Currently this API is targeting Cogl 2.0 so we will have time to integrate it properly with other upcoming Cogl 2.0 work. The basic reasons for the rename are: - That the term "material" implies to many people that they are constrained to fragment processing; perhaps as some kind of high-level texture abstraction. - In Clutter they get exposed by ClutterTexture actors which may be re-inforcing this misconception. - When comparing how other frameworks use the term material, a material sometimes describes a multi-pass fragment processing technique which isn't the case in Cogl. - In code, "CoglPipeline" will hopefully be a much more self documenting summary of what these objects represent; a full GPU pipeline configuration including, for example, vertex processing, fragment processing and blending. - When considering the API documentation story, at some point we need a document introducing developers to how the "GPU pipeline" works so it should become intuitive that CoglPipeline maps back to that description of the GPU pipeline. - This is consistent in terminology and concept to OpenGL 4's new pipeline object which is a container for program objects. Note: The cogl-material.[ch] files have been renamed to cogl-material-compat.[ch] because otherwise git doesn't seem to treat the change as a moving the old cogl-material.c->cogl-pipeline.c and so we loose all our git-blame history.
2010-10-27 17:54:57 +00:00
#include "cogl-pipeline-opengl-private.h"
#include "cogl-framebuffer-private.h"
#ifdef COGL_HAS_EGL_SUPPORT
#include "cogl-winsys-egl-private.h"
#endif
#include <string.h>
#include <math.h>
#ifdef COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT
#include "cogl-wayland-server.h"
#endif
static void _cogl_texture_2d_free (CoglTexture2D *tex_2d);
COGL_TEXTURE_DEFINE (Texture2D, texture_2d);
static const CoglTextureVtable cogl_texture_2d_vtable;
typedef struct _CoglTexture2DManualRepeatData
{
CoglTexture2D *tex_2d;
CoglMetaTextureCallback callback;
void *user_data;
} CoglTexture2DManualRepeatData;
static void
_cogl_texture_2d_set_wrap_mode_parameters (CoglTexture *tex,
GLenum wrap_mode_s,
GLenum wrap_mode_t,
GLenum wrap_mode_p)
{
CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex);
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* Only set the wrap mode if it's different from the current value
to avoid too many GL calls. Texture 2D doesn't make use of the r
coordinate so we can ignore its wrap mode */
if (tex_2d->wrap_mode_s != wrap_mode_s ||
tex_2d->wrap_mode_t != wrap_mode_t)
{
_cogl_bind_gl_texture_transient (GL_TEXTURE_2D,
tex_2d->gl_texture,
tex_2d->is_foreign);
GE( ctx, glTexParameteri (GL_TEXTURE_2D,
GL_TEXTURE_WRAP_S,
wrap_mode_s) );
GE( ctx, glTexParameteri (GL_TEXTURE_2D,
GL_TEXTURE_WRAP_T,
wrap_mode_t) );
tex_2d->wrap_mode_s = wrap_mode_s;
tex_2d->wrap_mode_t = wrap_mode_t;
}
}
static void
_cogl_texture_2d_free (CoglTexture2D *tex_2d)
{
if (!tex_2d->is_foreign)
_cogl_delete_gl_texture (tex_2d->gl_texture);
/* Chain up */
_cogl_texture_free (COGL_TEXTURE (tex_2d));
}
static gboolean
_cogl_texture_2d_can_create (unsigned int width,
unsigned int height,
CoglPixelFormat internal_format)
{
GLenum gl_intformat;
GLenum gl_type;
_COGL_GET_CONTEXT (ctx, FALSE);
/* If NPOT textures aren't supported then the size must be a power
of two */
if (!cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT) &&
(!_cogl_util_is_pot (width) ||
!_cogl_util_is_pot (height)))
return FALSE;
ctx->driver_vtable->pixel_format_to_gl (ctx,
internal_format,
&gl_intformat,
NULL,
&gl_type);
/* Check that the driver can create a texture with that size */
if (!ctx->texture_driver->size_supported (ctx,
GL_TEXTURE_2D,
gl_intformat,
gl_type,
width,
height))
return FALSE;
return TRUE;
}
static void
_cogl_texture_2d_set_auto_mipmap (CoglTexture *tex,
gboolean value)
{
CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex);
tex_2d->auto_mipmap = value;
}
static CoglTexture2D *
_cogl_texture_2d_create_base (unsigned int width,
unsigned int height,
CoglPixelFormat internal_format)
{
CoglTexture2D *tex_2d = g_new (CoglTexture2D, 1);
CoglTexture *tex = COGL_TEXTURE (tex_2d);
_cogl_texture_init (tex, &cogl_texture_2d_vtable);
tex_2d->width = width;
tex_2d->height = height;
tex_2d->mipmaps_dirty = TRUE;
tex_2d->auto_mipmap = TRUE;
/* We default to GL_LINEAR for both filters */
tex_2d->min_filter = GL_LINEAR;
tex_2d->mag_filter = GL_LINEAR;
/* Wrap mode not yet set */
tex_2d->wrap_mode_s = GL_FALSE;
tex_2d->wrap_mode_t = GL_FALSE;
tex_2d->is_foreign = FALSE;
tex_2d->format = internal_format;
return tex_2d;
}
CoglTexture2D *
cogl_texture_2d_new_with_size (CoglContext *ctx,
int width,
int height,
CoglPixelFormat internal_format,
GError **error)
{
CoglTexture2D *tex_2d;
GLenum gl_intformat;
GLenum gl_format;
GLenum gl_type;
/* Since no data, we need some internal format */
if (internal_format == COGL_PIXEL_FORMAT_ANY)
internal_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE;
if (!_cogl_texture_2d_can_create (width, height, internal_format))
{
g_set_error (error, COGL_TEXTURE_ERROR,
COGL_TEXTURE_ERROR_SIZE,
"Failed to create texture 2d due to size/format"
" constraints");
return NULL;
}
internal_format = ctx->driver_vtable->pixel_format_to_gl (ctx,
internal_format,
&gl_intformat,
&gl_format,
&gl_type);
tex_2d = _cogl_texture_2d_create_base (width, height,
internal_format);
ctx->texture_driver->gen (ctx, GL_TEXTURE_2D, 1, &tex_2d->gl_texture);
_cogl_bind_gl_texture_transient (GL_TEXTURE_2D,
tex_2d->gl_texture,
tex_2d->is_foreign);
GE( ctx, glTexImage2D (GL_TEXTURE_2D, 0, gl_intformat,
width, height, 0, gl_format, gl_type, NULL) );
return _cogl_texture_2d_handle_new (tex_2d);
}
CoglTexture2D *
cogl_texture_2d_new_from_bitmap (CoglBitmap *bmp,
CoglPixelFormat internal_format,
GError **error)
{
CoglTexture2D *tex_2d;
cogl-bitmap: Encapsulate the CoglBitmap even internally The CoglBitmap struct is now only defined within cogl-bitmap.c so that all of its members can now only be accessed with accessor functions. To get to the data pointer for the bitmap image you must first call _cogl_bitmap_map and later call _cogl_bitmap_unmap. The map function takes the same arguments as cogl_pixel_array_map so that eventually we can make a bitmap optionally internally divert to a pixel array. There is a _cogl_bitmap_new_from_data function which constructs a new bitmap object and takes ownership of the data pointer. The function gets passed a destroy callback which gets called when the bitmap is freed. This is similar to how gdk_pixbuf_new_from_data works. Alternatively NULL can be passed for the destroy function which means that the caller will manage the life of the pointer (but must guarantee that it stays alive at least until the bitmap is freed). This mechanism is used instead of the old approach of creating a CoglBitmap struct on the stack and manually filling in the members. It could also later be used to create a CoglBitmap that owns a GdkPixbuf ref so that we don't necessarily have to copy the GdkPixbuf data when converting to a bitmap. There is also _cogl_bitmap_new_shared. This creates a bitmap using a reference to another CoglBitmap for the data. This is a bit of a hack but it is needed by the atlas texture backend which wants to divert the set_region virtual to another texture but it needs to override the format of the bitmap to ignore the premult flag.
2010-07-07 17:44:16 +00:00
CoglBitmap *dst_bmp;
GLenum gl_intformat;
GLenum gl_format;
GLenum gl_type;
cogl-bitmap: Encapsulate the CoglBitmap even internally The CoglBitmap struct is now only defined within cogl-bitmap.c so that all of its members can now only be accessed with accessor functions. To get to the data pointer for the bitmap image you must first call _cogl_bitmap_map and later call _cogl_bitmap_unmap. The map function takes the same arguments as cogl_pixel_array_map so that eventually we can make a bitmap optionally internally divert to a pixel array. There is a _cogl_bitmap_new_from_data function which constructs a new bitmap object and takes ownership of the data pointer. The function gets passed a destroy callback which gets called when the bitmap is freed. This is similar to how gdk_pixbuf_new_from_data works. Alternatively NULL can be passed for the destroy function which means that the caller will manage the life of the pointer (but must guarantee that it stays alive at least until the bitmap is freed). This mechanism is used instead of the old approach of creating a CoglBitmap struct on the stack and manually filling in the members. It could also later be used to create a CoglBitmap that owns a GdkPixbuf ref so that we don't necessarily have to copy the GdkPixbuf data when converting to a bitmap. There is also _cogl_bitmap_new_shared. This creates a bitmap using a reference to another CoglBitmap for the data. This is a bit of a hack but it is needed by the atlas texture backend which wants to divert the set_region virtual to another texture but it needs to override the format of the bitmap to ignore the premult flag.
2010-07-07 17:44:16 +00:00
guint8 *data;
CoglContext *ctx;
_COGL_RETURN_VAL_IF_FAIL (bmp != NULL, COGL_INVALID_HANDLE);
ctx = _cogl_bitmap_get_context (bmp);
cogl-bitmap: Encapsulate the CoglBitmap even internally The CoglBitmap struct is now only defined within cogl-bitmap.c so that all of its members can now only be accessed with accessor functions. To get to the data pointer for the bitmap image you must first call _cogl_bitmap_map and later call _cogl_bitmap_unmap. The map function takes the same arguments as cogl_pixel_array_map so that eventually we can make a bitmap optionally internally divert to a pixel array. There is a _cogl_bitmap_new_from_data function which constructs a new bitmap object and takes ownership of the data pointer. The function gets passed a destroy callback which gets called when the bitmap is freed. This is similar to how gdk_pixbuf_new_from_data works. Alternatively NULL can be passed for the destroy function which means that the caller will manage the life of the pointer (but must guarantee that it stays alive at least until the bitmap is freed). This mechanism is used instead of the old approach of creating a CoglBitmap struct on the stack and manually filling in the members. It could also later be used to create a CoglBitmap that owns a GdkPixbuf ref so that we don't necessarily have to copy the GdkPixbuf data when converting to a bitmap. There is also _cogl_bitmap_new_shared. This creates a bitmap using a reference to another CoglBitmap for the data. This is a bit of a hack but it is needed by the atlas texture backend which wants to divert the set_region virtual to another texture but it needs to override the format of the bitmap to ignore the premult flag.
2010-07-07 17:44:16 +00:00
internal_format =
_cogl_texture_determine_internal_format (cogl_bitmap_get_format (bmp),
cogl-bitmap: Encapsulate the CoglBitmap even internally The CoglBitmap struct is now only defined within cogl-bitmap.c so that all of its members can now only be accessed with accessor functions. To get to the data pointer for the bitmap image you must first call _cogl_bitmap_map and later call _cogl_bitmap_unmap. The map function takes the same arguments as cogl_pixel_array_map so that eventually we can make a bitmap optionally internally divert to a pixel array. There is a _cogl_bitmap_new_from_data function which constructs a new bitmap object and takes ownership of the data pointer. The function gets passed a destroy callback which gets called when the bitmap is freed. This is similar to how gdk_pixbuf_new_from_data works. Alternatively NULL can be passed for the destroy function which means that the caller will manage the life of the pointer (but must guarantee that it stays alive at least until the bitmap is freed). This mechanism is used instead of the old approach of creating a CoglBitmap struct on the stack and manually filling in the members. It could also later be used to create a CoglBitmap that owns a GdkPixbuf ref so that we don't necessarily have to copy the GdkPixbuf data when converting to a bitmap. There is also _cogl_bitmap_new_shared. This creates a bitmap using a reference to another CoglBitmap for the data. This is a bit of a hack but it is needed by the atlas texture backend which wants to divert the set_region virtual to another texture but it needs to override the format of the bitmap to ignore the premult flag.
2010-07-07 17:44:16 +00:00
internal_format);
if (!_cogl_texture_2d_can_create (cogl_bitmap_get_width (bmp),
cogl_bitmap_get_height (bmp),
cogl-bitmap: Encapsulate the CoglBitmap even internally The CoglBitmap struct is now only defined within cogl-bitmap.c so that all of its members can now only be accessed with accessor functions. To get to the data pointer for the bitmap image you must first call _cogl_bitmap_map and later call _cogl_bitmap_unmap. The map function takes the same arguments as cogl_pixel_array_map so that eventually we can make a bitmap optionally internally divert to a pixel array. There is a _cogl_bitmap_new_from_data function which constructs a new bitmap object and takes ownership of the data pointer. The function gets passed a destroy callback which gets called when the bitmap is freed. This is similar to how gdk_pixbuf_new_from_data works. Alternatively NULL can be passed for the destroy function which means that the caller will manage the life of the pointer (but must guarantee that it stays alive at least until the bitmap is freed). This mechanism is used instead of the old approach of creating a CoglBitmap struct on the stack and manually filling in the members. It could also later be used to create a CoglBitmap that owns a GdkPixbuf ref so that we don't necessarily have to copy the GdkPixbuf data when converting to a bitmap. There is also _cogl_bitmap_new_shared. This creates a bitmap using a reference to another CoglBitmap for the data. This is a bit of a hack but it is needed by the atlas texture backend which wants to divert the set_region virtual to another texture but it needs to override the format of the bitmap to ignore the premult flag.
2010-07-07 17:44:16 +00:00
internal_format))
{
g_set_error (error, COGL_TEXTURE_ERROR,
COGL_TEXTURE_ERROR_SIZE,
"Failed to create texture 2d due to size/format"
" constraints");
return NULL;
}
cogl-bitmap: Encapsulate the CoglBitmap even internally The CoglBitmap struct is now only defined within cogl-bitmap.c so that all of its members can now only be accessed with accessor functions. To get to the data pointer for the bitmap image you must first call _cogl_bitmap_map and later call _cogl_bitmap_unmap. The map function takes the same arguments as cogl_pixel_array_map so that eventually we can make a bitmap optionally internally divert to a pixel array. There is a _cogl_bitmap_new_from_data function which constructs a new bitmap object and takes ownership of the data pointer. The function gets passed a destroy callback which gets called when the bitmap is freed. This is similar to how gdk_pixbuf_new_from_data works. Alternatively NULL can be passed for the destroy function which means that the caller will manage the life of the pointer (but must guarantee that it stays alive at least until the bitmap is freed). This mechanism is used instead of the old approach of creating a CoglBitmap struct on the stack and manually filling in the members. It could also later be used to create a CoglBitmap that owns a GdkPixbuf ref so that we don't necessarily have to copy the GdkPixbuf data when converting to a bitmap. There is also _cogl_bitmap_new_shared. This creates a bitmap using a reference to another CoglBitmap for the data. This is a bit of a hack but it is needed by the atlas texture backend which wants to divert the set_region virtual to another texture but it needs to override the format of the bitmap to ignore the premult flag.
2010-07-07 17:44:16 +00:00
if ((dst_bmp = _cogl_texture_prepare_for_upload (bmp,
internal_format,
&internal_format,
&gl_intformat,
&gl_format,
&gl_type)) == NULL)
{
g_set_error (error, COGL_TEXTURE_ERROR,
COGL_TEXTURE_ERROR_FORMAT,
"Failed to prepare texture upload due to format");
return NULL;
}
tex_2d = _cogl_texture_2d_create_base (cogl_bitmap_get_width (bmp),
cogl_bitmap_get_height (bmp),
internal_format);
/* Keep a copy of the first pixel so that if glGenerateMipmap isn't
supported we can fallback to using GL_GENERATE_MIPMAP */
if (!cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN) &&
cogl-bitmap: Encapsulate the CoglBitmap even internally The CoglBitmap struct is now only defined within cogl-bitmap.c so that all of its members can now only be accessed with accessor functions. To get to the data pointer for the bitmap image you must first call _cogl_bitmap_map and later call _cogl_bitmap_unmap. The map function takes the same arguments as cogl_pixel_array_map so that eventually we can make a bitmap optionally internally divert to a pixel array. There is a _cogl_bitmap_new_from_data function which constructs a new bitmap object and takes ownership of the data pointer. The function gets passed a destroy callback which gets called when the bitmap is freed. This is similar to how gdk_pixbuf_new_from_data works. Alternatively NULL can be passed for the destroy function which means that the caller will manage the life of the pointer (but must guarantee that it stays alive at least until the bitmap is freed). This mechanism is used instead of the old approach of creating a CoglBitmap struct on the stack and manually filling in the members. It could also later be used to create a CoglBitmap that owns a GdkPixbuf ref so that we don't necessarily have to copy the GdkPixbuf data when converting to a bitmap. There is also _cogl_bitmap_new_shared. This creates a bitmap using a reference to another CoglBitmap for the data. This is a bit of a hack but it is needed by the atlas texture backend which wants to divert the set_region virtual to another texture but it needs to override the format of the bitmap to ignore the premult flag.
2010-07-07 17:44:16 +00:00
(data = _cogl_bitmap_map (dst_bmp,
COGL_BUFFER_ACCESS_READ, 0)))
{
CoglPixelFormat format = cogl_bitmap_get_format (dst_bmp);
cogl-bitmap: Encapsulate the CoglBitmap even internally The CoglBitmap struct is now only defined within cogl-bitmap.c so that all of its members can now only be accessed with accessor functions. To get to the data pointer for the bitmap image you must first call _cogl_bitmap_map and later call _cogl_bitmap_unmap. The map function takes the same arguments as cogl_pixel_array_map so that eventually we can make a bitmap optionally internally divert to a pixel array. There is a _cogl_bitmap_new_from_data function which constructs a new bitmap object and takes ownership of the data pointer. The function gets passed a destroy callback which gets called when the bitmap is freed. This is similar to how gdk_pixbuf_new_from_data works. Alternatively NULL can be passed for the destroy function which means that the caller will manage the life of the pointer (but must guarantee that it stays alive at least until the bitmap is freed). This mechanism is used instead of the old approach of creating a CoglBitmap struct on the stack and manually filling in the members. It could also later be used to create a CoglBitmap that owns a GdkPixbuf ref so that we don't necessarily have to copy the GdkPixbuf data when converting to a bitmap. There is also _cogl_bitmap_new_shared. This creates a bitmap using a reference to another CoglBitmap for the data. This is a bit of a hack but it is needed by the atlas texture backend which wants to divert the set_region virtual to another texture but it needs to override the format of the bitmap to ignore the premult flag.
2010-07-07 17:44:16 +00:00
tex_2d->first_pixel.gl_format = gl_format;
tex_2d->first_pixel.gl_type = gl_type;
memcpy (tex_2d->first_pixel.data, data,
_cogl_pixel_format_get_bytes_per_pixel (format));
cogl-bitmap: Encapsulate the CoglBitmap even internally The CoglBitmap struct is now only defined within cogl-bitmap.c so that all of its members can now only be accessed with accessor functions. To get to the data pointer for the bitmap image you must first call _cogl_bitmap_map and later call _cogl_bitmap_unmap. The map function takes the same arguments as cogl_pixel_array_map so that eventually we can make a bitmap optionally internally divert to a pixel array. There is a _cogl_bitmap_new_from_data function which constructs a new bitmap object and takes ownership of the data pointer. The function gets passed a destroy callback which gets called when the bitmap is freed. This is similar to how gdk_pixbuf_new_from_data works. Alternatively NULL can be passed for the destroy function which means that the caller will manage the life of the pointer (but must guarantee that it stays alive at least until the bitmap is freed). This mechanism is used instead of the old approach of creating a CoglBitmap struct on the stack and manually filling in the members. It could also later be used to create a CoglBitmap that owns a GdkPixbuf ref so that we don't necessarily have to copy the GdkPixbuf data when converting to a bitmap. There is also _cogl_bitmap_new_shared. This creates a bitmap using a reference to another CoglBitmap for the data. This is a bit of a hack but it is needed by the atlas texture backend which wants to divert the set_region virtual to another texture but it needs to override the format of the bitmap to ignore the premult flag.
2010-07-07 17:44:16 +00:00
_cogl_bitmap_unmap (dst_bmp);
}
ctx->texture_driver->gen (ctx, GL_TEXTURE_2D, 1, &tex_2d->gl_texture);
ctx->texture_driver->upload_to_gl (ctx,
GL_TEXTURE_2D,
tex_2d->gl_texture,
FALSE,
cogl-bitmap: Encapsulate the CoglBitmap even internally The CoglBitmap struct is now only defined within cogl-bitmap.c so that all of its members can now only be accessed with accessor functions. To get to the data pointer for the bitmap image you must first call _cogl_bitmap_map and later call _cogl_bitmap_unmap. The map function takes the same arguments as cogl_pixel_array_map so that eventually we can make a bitmap optionally internally divert to a pixel array. There is a _cogl_bitmap_new_from_data function which constructs a new bitmap object and takes ownership of the data pointer. The function gets passed a destroy callback which gets called when the bitmap is freed. This is similar to how gdk_pixbuf_new_from_data works. Alternatively NULL can be passed for the destroy function which means that the caller will manage the life of the pointer (but must guarantee that it stays alive at least until the bitmap is freed). This mechanism is used instead of the old approach of creating a CoglBitmap struct on the stack and manually filling in the members. It could also later be used to create a CoglBitmap that owns a GdkPixbuf ref so that we don't necessarily have to copy the GdkPixbuf data when converting to a bitmap. There is also _cogl_bitmap_new_shared. This creates a bitmap using a reference to another CoglBitmap for the data. This is a bit of a hack but it is needed by the atlas texture backend which wants to divert the set_region virtual to another texture but it needs to override the format of the bitmap to ignore the premult flag.
2010-07-07 17:44:16 +00:00
dst_bmp,
gl_intformat,
gl_format,
gl_type);
tex_2d->gl_format = gl_intformat;
cogl-bitmap: Encapsulate the CoglBitmap even internally The CoglBitmap struct is now only defined within cogl-bitmap.c so that all of its members can now only be accessed with accessor functions. To get to the data pointer for the bitmap image you must first call _cogl_bitmap_map and later call _cogl_bitmap_unmap. The map function takes the same arguments as cogl_pixel_array_map so that eventually we can make a bitmap optionally internally divert to a pixel array. There is a _cogl_bitmap_new_from_data function which constructs a new bitmap object and takes ownership of the data pointer. The function gets passed a destroy callback which gets called when the bitmap is freed. This is similar to how gdk_pixbuf_new_from_data works. Alternatively NULL can be passed for the destroy function which means that the caller will manage the life of the pointer (but must guarantee that it stays alive at least until the bitmap is freed). This mechanism is used instead of the old approach of creating a CoglBitmap struct on the stack and manually filling in the members. It could also later be used to create a CoglBitmap that owns a GdkPixbuf ref so that we don't necessarily have to copy the GdkPixbuf data when converting to a bitmap. There is also _cogl_bitmap_new_shared. This creates a bitmap using a reference to another CoglBitmap for the data. This is a bit of a hack but it is needed by the atlas texture backend which wants to divert the set_region virtual to another texture but it needs to override the format of the bitmap to ignore the premult flag.
2010-07-07 17:44:16 +00:00
cogl_object_unref (dst_bmp);
return _cogl_texture_2d_handle_new (tex_2d);
}
CoglTexture2D *
cogl_texture_2d_new_from_data (CoglContext *ctx,
int width,
int height,
CoglPixelFormat format,
CoglPixelFormat internal_format,
int rowstride,
const guint8 *data,
GError **error)
{
CoglBitmap *bmp;
CoglHandle tex;
_COGL_RETURN_VAL_IF_FAIL (format != COGL_PIXEL_FORMAT_ANY, NULL);
_COGL_RETURN_VAL_IF_FAIL (data != NULL, NULL);
/* Rowstride from width if not given */
if (rowstride == 0)
rowstride = width * _cogl_pixel_format_get_bytes_per_pixel (format);
/* Wrap the data into a bitmap */
bmp = cogl_bitmap_new_for_data (ctx,
width, height,
format,
rowstride,
(guint8 *) data);
tex = cogl_texture_2d_new_from_bitmap (bmp,
internal_format,
error);
cogl_object_unref (bmp);
return tex;
}
CoglTexture2D *
cogl_texture_2d_new_from_foreign (CoglContext *ctx,
GLuint gl_handle,
int width,
int height,
CoglPixelFormat format,
GError **error)
{
/* NOTE: width, height and internal format are not queriable
* in GLES, hence such a function prototype.
*/
GLenum gl_error = 0;
GLint gl_compressed = GL_FALSE;
GLenum gl_int_format = 0;
CoglTexture2D *tex_2d;
if (!ctx->texture_driver->allows_foreign_gl_target (ctx, GL_TEXTURE_2D))
return COGL_INVALID_HANDLE;
/* Make sure it is a valid GL texture object */
if (!ctx->glIsTexture (gl_handle))
return COGL_INVALID_HANDLE;
/* Make sure binding succeeds */
while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR)
;
_cogl_bind_gl_texture_transient (GL_TEXTURE_2D, gl_handle, TRUE);
if (ctx->glGetError () != GL_NO_ERROR)
return COGL_INVALID_HANDLE;
/* Obtain texture parameters
(only level 0 we are interested in) */
#if HAVE_COGL_GL
Dynamically load the GL or GLES library The GL or GLES library is now dynamically loaded by the CoglRenderer so that it can choose between GL, GLES1 and GLES2 at runtime. The library is loaded by the renderer because it needs to be done before calling eglInitialize. There is a new environment variable called COGL_DRIVER to choose between gl, gles1 or gles2. The #ifdefs for HAVE_COGL_GL, HAVE_COGL_GLES and HAVE_COGL_GLES2 have been changed so that they don't assume the ifdefs are mutually exclusive. They haven't been removed entirely so that it's possible to compile the GLES backends without the the enums from the GL headers. When using GLX the winsys additionally dynamically loads libGL because that also contains the GLX API. It can't be linked in directly because that would probably conflict with the GLES API if the EGL is selected. When compiling with EGL support the library links directly to libEGL because it doesn't contain any GL API so it shouldn't have any conflicts. When building for WGL or OSX Cogl still directly links against the GL API so there is a #define in config.h so that Cogl won't try to dlopen the library. Cogl-pango previously had a #ifdef to detect when the GL backend is used so that it can sneakily pass GL_QUADS to cogl_vertex_buffer_draw. This is now changed so that it queries the CoglContext for the backend. However to get this to work Cogl now needs to export the _cogl_context_get_default symbol and cogl-pango needs some extra -I flags to so that it can include cogl-context-private.h
2011-07-07 19:44:56 +00:00
if (ctx->driver == COGL_DRIVER_GL)
{
GE( ctx, glGetTexLevelParameteriv (GL_TEXTURE_2D, 0,
GL_TEXTURE_COMPRESSED,
&gl_compressed) );
Dynamically load the GL or GLES library The GL or GLES library is now dynamically loaded by the CoglRenderer so that it can choose between GL, GLES1 and GLES2 at runtime. The library is loaded by the renderer because it needs to be done before calling eglInitialize. There is a new environment variable called COGL_DRIVER to choose between gl, gles1 or gles2. The #ifdefs for HAVE_COGL_GL, HAVE_COGL_GLES and HAVE_COGL_GLES2 have been changed so that they don't assume the ifdefs are mutually exclusive. They haven't been removed entirely so that it's possible to compile the GLES backends without the the enums from the GL headers. When using GLX the winsys additionally dynamically loads libGL because that also contains the GLX API. It can't be linked in directly because that would probably conflict with the GLES API if the EGL is selected. When compiling with EGL support the library links directly to libEGL because it doesn't contain any GL API so it shouldn't have any conflicts. When building for WGL or OSX Cogl still directly links against the GL API so there is a #define in config.h so that Cogl won't try to dlopen the library. Cogl-pango previously had a #ifdef to detect when the GL backend is used so that it can sneakily pass GL_QUADS to cogl_vertex_buffer_draw. This is now changed so that it queries the CoglContext for the backend. However to get this to work Cogl now needs to export the _cogl_context_get_default symbol and cogl-pango needs some extra -I flags to so that it can include cogl-context-private.h
2011-07-07 19:44:56 +00:00
{
GLint val;
Dynamically load the GL or GLES library The GL or GLES library is now dynamically loaded by the CoglRenderer so that it can choose between GL, GLES1 and GLES2 at runtime. The library is loaded by the renderer because it needs to be done before calling eglInitialize. There is a new environment variable called COGL_DRIVER to choose between gl, gles1 or gles2. The #ifdefs for HAVE_COGL_GL, HAVE_COGL_GLES and HAVE_COGL_GLES2 have been changed so that they don't assume the ifdefs are mutually exclusive. They haven't been removed entirely so that it's possible to compile the GLES backends without the the enums from the GL headers. When using GLX the winsys additionally dynamically loads libGL because that also contains the GLX API. It can't be linked in directly because that would probably conflict with the GLES API if the EGL is selected. When compiling with EGL support the library links directly to libEGL because it doesn't contain any GL API so it shouldn't have any conflicts. When building for WGL or OSX Cogl still directly links against the GL API so there is a #define in config.h so that Cogl won't try to dlopen the library. Cogl-pango previously had a #ifdef to detect when the GL backend is used so that it can sneakily pass GL_QUADS to cogl_vertex_buffer_draw. This is now changed so that it queries the CoglContext for the backend. However to get this to work Cogl now needs to export the _cogl_context_get_default symbol and cogl-pango needs some extra -I flags to so that it can include cogl-context-private.h
2011-07-07 19:44:56 +00:00
GE( ctx, glGetTexLevelParameteriv (GL_TEXTURE_2D, 0,
GL_TEXTURE_INTERNAL_FORMAT,
&val) );
Dynamically load the GL or GLES library The GL or GLES library is now dynamically loaded by the CoglRenderer so that it can choose between GL, GLES1 and GLES2 at runtime. The library is loaded by the renderer because it needs to be done before calling eglInitialize. There is a new environment variable called COGL_DRIVER to choose between gl, gles1 or gles2. The #ifdefs for HAVE_COGL_GL, HAVE_COGL_GLES and HAVE_COGL_GLES2 have been changed so that they don't assume the ifdefs are mutually exclusive. They haven't been removed entirely so that it's possible to compile the GLES backends without the the enums from the GL headers. When using GLX the winsys additionally dynamically loads libGL because that also contains the GLX API. It can't be linked in directly because that would probably conflict with the GLES API if the EGL is selected. When compiling with EGL support the library links directly to libEGL because it doesn't contain any GL API so it shouldn't have any conflicts. When building for WGL or OSX Cogl still directly links against the GL API so there is a #define in config.h so that Cogl won't try to dlopen the library. Cogl-pango previously had a #ifdef to detect when the GL backend is used so that it can sneakily pass GL_QUADS to cogl_vertex_buffer_draw. This is now changed so that it queries the CoglContext for the backend. However to get this to work Cogl now needs to export the _cogl_context_get_default symbol and cogl-pango needs some extra -I flags to so that it can include cogl-context-private.h
2011-07-07 19:44:56 +00:00
gl_int_format = val;
}
Dynamically load the GL or GLES library The GL or GLES library is now dynamically loaded by the CoglRenderer so that it can choose between GL, GLES1 and GLES2 at runtime. The library is loaded by the renderer because it needs to be done before calling eglInitialize. There is a new environment variable called COGL_DRIVER to choose between gl, gles1 or gles2. The #ifdefs for HAVE_COGL_GL, HAVE_COGL_GLES and HAVE_COGL_GLES2 have been changed so that they don't assume the ifdefs are mutually exclusive. They haven't been removed entirely so that it's possible to compile the GLES backends without the the enums from the GL headers. When using GLX the winsys additionally dynamically loads libGL because that also contains the GLX API. It can't be linked in directly because that would probably conflict with the GLES API if the EGL is selected. When compiling with EGL support the library links directly to libEGL because it doesn't contain any GL API so it shouldn't have any conflicts. When building for WGL or OSX Cogl still directly links against the GL API so there is a #define in config.h so that Cogl won't try to dlopen the library. Cogl-pango previously had a #ifdef to detect when the GL backend is used so that it can sneakily pass GL_QUADS to cogl_vertex_buffer_draw. This is now changed so that it queries the CoglContext for the backend. However to get this to work Cogl now needs to export the _cogl_context_get_default symbol and cogl-pango needs some extra -I flags to so that it can include cogl-context-private.h
2011-07-07 19:44:56 +00:00
/* If we can query GL for the actual pixel format then we'll ignore
the passed in format and use that. */
if (!ctx->driver_vtable->pixel_format_from_gl_internal (ctx,
gl_int_format,
&format))
Dynamically load the GL or GLES library The GL or GLES library is now dynamically loaded by the CoglRenderer so that it can choose between GL, GLES1 and GLES2 at runtime. The library is loaded by the renderer because it needs to be done before calling eglInitialize. There is a new environment variable called COGL_DRIVER to choose between gl, gles1 or gles2. The #ifdefs for HAVE_COGL_GL, HAVE_COGL_GLES and HAVE_COGL_GLES2 have been changed so that they don't assume the ifdefs are mutually exclusive. They haven't been removed entirely so that it's possible to compile the GLES backends without the the enums from the GL headers. When using GLX the winsys additionally dynamically loads libGL because that also contains the GLX API. It can't be linked in directly because that would probably conflict with the GLES API if the EGL is selected. When compiling with EGL support the library links directly to libEGL because it doesn't contain any GL API so it shouldn't have any conflicts. When building for WGL or OSX Cogl still directly links against the GL API so there is a #define in config.h so that Cogl won't try to dlopen the library. Cogl-pango previously had a #ifdef to detect when the GL backend is used so that it can sneakily pass GL_QUADS to cogl_vertex_buffer_draw. This is now changed so that it queries the CoglContext for the backend. However to get this to work Cogl now needs to export the _cogl_context_get_default symbol and cogl-pango needs some extra -I flags to so that it can include cogl-context-private.h
2011-07-07 19:44:56 +00:00
return COGL_INVALID_HANDLE;
}
else
#endif
Dynamically load the GL or GLES library The GL or GLES library is now dynamically loaded by the CoglRenderer so that it can choose between GL, GLES1 and GLES2 at runtime. The library is loaded by the renderer because it needs to be done before calling eglInitialize. There is a new environment variable called COGL_DRIVER to choose between gl, gles1 or gles2. The #ifdefs for HAVE_COGL_GL, HAVE_COGL_GLES and HAVE_COGL_GLES2 have been changed so that they don't assume the ifdefs are mutually exclusive. They haven't been removed entirely so that it's possible to compile the GLES backends without the the enums from the GL headers. When using GLX the winsys additionally dynamically loads libGL because that also contains the GLX API. It can't be linked in directly because that would probably conflict with the GLES API if the EGL is selected. When compiling with EGL support the library links directly to libEGL because it doesn't contain any GL API so it shouldn't have any conflicts. When building for WGL or OSX Cogl still directly links against the GL API so there is a #define in config.h so that Cogl won't try to dlopen the library. Cogl-pango previously had a #ifdef to detect when the GL backend is used so that it can sneakily pass GL_QUADS to cogl_vertex_buffer_draw. This is now changed so that it queries the CoglContext for the backend. However to get this to work Cogl now needs to export the _cogl_context_get_default symbol and cogl-pango needs some extra -I flags to so that it can include cogl-context-private.h
2011-07-07 19:44:56 +00:00
{
/* Otherwise we'll assume we can derive the GL format from the
passed in format */
ctx->driver_vtable->pixel_format_to_gl (ctx,
format,
&gl_int_format,
NULL,
NULL);
Dynamically load the GL or GLES library The GL or GLES library is now dynamically loaded by the CoglRenderer so that it can choose between GL, GLES1 and GLES2 at runtime. The library is loaded by the renderer because it needs to be done before calling eglInitialize. There is a new environment variable called COGL_DRIVER to choose between gl, gles1 or gles2. The #ifdefs for HAVE_COGL_GL, HAVE_COGL_GLES and HAVE_COGL_GLES2 have been changed so that they don't assume the ifdefs are mutually exclusive. They haven't been removed entirely so that it's possible to compile the GLES backends without the the enums from the GL headers. When using GLX the winsys additionally dynamically loads libGL because that also contains the GLX API. It can't be linked in directly because that would probably conflict with the GLES API if the EGL is selected. When compiling with EGL support the library links directly to libEGL because it doesn't contain any GL API so it shouldn't have any conflicts. When building for WGL or OSX Cogl still directly links against the GL API so there is a #define in config.h so that Cogl won't try to dlopen the library. Cogl-pango previously had a #ifdef to detect when the GL backend is used so that it can sneakily pass GL_QUADS to cogl_vertex_buffer_draw. This is now changed so that it queries the CoglContext for the backend. However to get this to work Cogl now needs to export the _cogl_context_get_default symbol and cogl-pango needs some extra -I flags to so that it can include cogl-context-private.h
2011-07-07 19:44:56 +00:00
}
/* Note: We always trust the given width and height without querying
* the texture object because the user may be creating a Cogl
* texture for a texture_from_pixmap object where glTexImage2D may
* not have been called and the texture_from_pixmap spec doesn't
* clarify that it is reliable to query back the size from OpenGL.
*/
/* Validate width and height */
if (width <= 0 || height <= 0)
return COGL_INVALID_HANDLE;
/* Compressed texture images not supported */
if (gl_compressed == GL_TRUE)
return COGL_INVALID_HANDLE;
/* Note: previously this code would query the texture object for
whether it has GL_GENERATE_MIPMAP enabled to determine whether to
auto-generate the mipmap. This doesn't make much sense any more
since Cogl switch to using glGenerateMipmap. Ideally I think
cogl_texture_new_from_foreign should take a flags parameter so
that the application can decide whether it wants
auto-mipmapping. To be compatible with existing code, Cogl now
disables its own auto-mipmapping but leaves the value of
GL_GENERATE_MIPMAP alone so that it would still work but without
the dirtiness tracking that Cogl would do. */
/* Create new texture */
tex_2d = _cogl_texture_2d_create_base (width, height,
format);
_cogl_texture_2d_set_auto_mipmap (COGL_TEXTURE (tex_2d), FALSE);
/* Setup bitmap info */
tex_2d->is_foreign = TRUE;
tex_2d->mipmaps_dirty = TRUE;
tex_2d->format = format;
tex_2d->gl_texture = gl_handle;
tex_2d->gl_format = gl_int_format;
/* Unknown filter */
tex_2d->min_filter = GL_FALSE;
tex_2d->mag_filter = GL_FALSE;
return _cogl_texture_2d_handle_new (tex_2d);
}
#if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base)
/* NB: The reason we require the width, height and format to be passed
* even though they may seem redundant is because GLES 1/2 don't
* provide a way to query these properties. */
CoglTexture2D *
_cogl_egl_texture_2d_new_from_image (CoglContext *ctx,
int width,
int height,
CoglPixelFormat format,
EGLImageKHR image,
GError **error)
{
CoglTexture2D *tex_2d;
GLenum gl_error;
_COGL_RETURN_VAL_IF_FAIL (_cogl_context_get_winsys (ctx)->constraints &
COGL_RENDERER_CONSTRAINT_USES_EGL,
NULL);
_COGL_RETURN_VAL_IF_FAIL (ctx->private_feature_flags &
COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE,
NULL);
tex_2d = _cogl_texture_2d_create_base (width, height,
format);
ctx->texture_driver->gen (ctx, GL_TEXTURE_2D, 1, &tex_2d->gl_texture);
_cogl_bind_gl_texture_transient (GL_TEXTURE_2D,
tex_2d->gl_texture,
FALSE);
while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR)
;
ctx->glEGLImageTargetTexture2D (GL_TEXTURE_2D, image);
if (ctx->glGetError () != GL_NO_ERROR)
{
g_set_error (error,
COGL_TEXTURE_ERROR,
COGL_TEXTURE_ERROR_BAD_PARAMETER,
"Could not create a CoglTexture2D from a given EGLImage");
return NULL;
}
return _cogl_texture_2d_handle_new (tex_2d);
}
#endif /* defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base) */
#ifdef COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT
CoglTexture2D *
cogl_wayland_texture_2d_new_from_buffer (CoglContext *ctx,
struct wl_buffer *buffer,
GError **error)
{
if (wl_buffer_is_shm (buffer))
{
int stride = wl_shm_buffer_get_stride (buffer);
CoglPixelFormat format;
CoglPixelFormat internal_format = COGL_PIXEL_FORMAT_ANY;
switch (wl_shm_buffer_get_format (buffer))
{
#if G_BYTE_ORDER == G_BIG_ENDIAN
case WL_SHM_FORMAT_ARGB8888:
format = COGL_PIXEL_FORMAT_ARGB_8888_PRE;
break;
case WL_SHM_FORMAT_XRGB32:
format = COGL_PIXEL_FORMAT_ARGB_8888;
internal_format = COGL_PIXEL_FORMAT_RGB_888;
break;
#elif G_BYTE_ORDER == G_LITTLE_ENDIAN
case WL_SHM_FORMAT_ARGB8888:
format = COGL_PIXEL_FORMAT_BGRA_8888_PRE;
break;
case WL_SHM_FORMAT_XRGB8888:
format = COGL_PIXEL_FORMAT_BGRA_8888;
internal_format = COGL_PIXEL_FORMAT_BGR_888;
break;
#endif
default:
g_warn_if_reached ();
format = COGL_PIXEL_FORMAT_ARGB_8888;
}
return cogl_texture_2d_new_from_data (ctx,
buffer->width,
buffer->height,
format,
internal_format,
stride,
wl_shm_buffer_get_data (buffer),
error);
}
else
{
EGLImageKHR image;
CoglTexture2D *tex;
_COGL_RETURN_VAL_IF_FAIL (_cogl_context_get_winsys (ctx)->constraints &
COGL_RENDERER_CONSTRAINT_USES_EGL,
NULL);
image = _cogl_egl_create_image (ctx,
EGL_WAYLAND_BUFFER_WL,
buffer,
NULL);
tex = _cogl_egl_texture_2d_new_from_image (ctx,
buffer->width,
buffer->height,
COGL_PIXEL_FORMAT_ARGB_8888_PRE,
image,
error);
_cogl_egl_destroy_image (ctx, image);
return tex;
}
}
#endif /* COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT */
void
_cogl_texture_2d_externally_modified (CoglHandle handle)
{
if (!cogl_is_texture_2d (handle))
return;
COGL_TEXTURE_2D (handle)->mipmaps_dirty = TRUE;
}
void
_cogl_texture_2d_copy_from_framebuffer (CoglHandle handle,
int dst_x,
int dst_y,
int src_x,
int src_y,
int width,
int height)
{
CoglTexture2D *tex_2d;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
_COGL_RETURN_IF_FAIL (cogl_is_texture_2d (handle));
tex_2d = COGL_TEXTURE_2D (handle);
/* 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
* framebuffer. */
_cogl_framebuffer_flush_state (cogl_get_draw_framebuffer (),
_cogl_get_read_framebuffer (),
COGL_FRAMEBUFFER_STATE_ALL &
~COGL_FRAMEBUFFER_STATE_CLIP);
_cogl_bind_gl_texture_transient (GL_TEXTURE_2D,
tex_2d->gl_texture,
tex_2d->is_foreign);
ctx->glCopyTexSubImage2D (GL_TEXTURE_2D,
0, /* level */
dst_x, dst_y,
src_x, src_y,
width, height);
tex_2d->mipmaps_dirty = TRUE;
}
cogl: improves header and coding style consistency We've had complaints that our Cogl code/headers are a bit "special" so this is a first pass at tidying things up by giving them some consistency. These changes are all consistent with how new code in Cogl is being written, but the style isn't consistently applied across all code yet. There are two parts to this patch; but since each one required a large amount of effort to maintain tidy indenting it made sense to combine the changes to reduce the time spent re indenting the same lines. The first change is to use a consistent style for declaring function prototypes in headers. Cogl headers now consistently use this style for prototypes: return_type cogl_function_name (CoglType arg0, CoglType arg1); Not everyone likes this style, but it seems that most of the currently active Cogl developers agree on it. The second change is to constrain the use of redundant glib data types in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all been replaced with int, unsigned int, float, long, unsigned long and char respectively. When talking about pixel data; use of guchar has been replaced with guint8, otherwise unsigned char can be used. The glib types that we continue to use for portability are gboolean, gint{8,16,32,64}, guint{8,16,32,64} and gsize. The general intention is that Cogl should look palatable to the widest range of C programmers including those outside the Gnome community so - especially for the public API - we want to minimize the number of foreign looking typedefs.
2010-02-10 01:57:32 +00:00
static int
_cogl_texture_2d_get_max_waste (CoglTexture *tex)
{
return -1;
}
static gboolean
_cogl_texture_2d_is_sliced (CoglTexture *tex)
{
return FALSE;
}
static gboolean
_cogl_texture_2d_can_hardware_repeat (CoglTexture *tex)
{
return TRUE;
}
static void
_cogl_texture_2d_transform_coords_to_gl (CoglTexture *tex,
float *s,
float *t)
{
/* The texture coordinates map directly so we don't need to do
anything */
}
static CoglTransformResult
2010-01-18 09:22:04 +00:00
_cogl_texture_2d_transform_quad_coords_to_gl (CoglTexture *tex,
float *coords)
{
/* The texture coordinates map directly so we don't need to do
anything other than check for repeats */
gboolean need_repeat = FALSE;
int i;
for (i = 0; i < 4; i++)
if (coords[i] < 0.0f || coords[i] > 1.0f)
need_repeat = TRUE;
return (need_repeat ? COGL_TRANSFORM_HARDWARE_REPEAT
: COGL_TRANSFORM_NO_REPEAT);
2010-01-18 09:22:04 +00:00
}
static gboolean
_cogl_texture_2d_get_gl_texture (CoglTexture *tex,
GLuint *out_gl_handle,
GLenum *out_gl_target)
{
CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex);
if (out_gl_handle)
*out_gl_handle = tex_2d->gl_texture;
if (out_gl_target)
*out_gl_target = GL_TEXTURE_2D;
return TRUE;
}
static void
_cogl_texture_2d_set_filters (CoglTexture *tex,
GLenum min_filter,
GLenum mag_filter)
{
CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex);
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (min_filter == tex_2d->min_filter
&& mag_filter == tex_2d->mag_filter)
return;
/* Store new values */
tex_2d->min_filter = min_filter;
tex_2d->mag_filter = mag_filter;
/* Apply new filters to the texture */
_cogl_bind_gl_texture_transient (GL_TEXTURE_2D,
tex_2d->gl_texture,
tex_2d->is_foreign);
GE( ctx, glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter) );
GE( ctx, glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter) );
}
static void
_cogl_texture_2d_pre_paint (CoglTexture *tex, CoglTexturePrePaintFlags flags)
{
CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex);
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* Only update if the mipmaps are dirty */
if ((flags & COGL_TEXTURE_NEEDS_MIPMAP) &&
tex_2d->auto_mipmap && tex_2d->mipmaps_dirty)
{
_cogl_bind_gl_texture_transient (GL_TEXTURE_2D,
tex_2d->gl_texture,
tex_2d->is_foreign);
/* glGenerateMipmap is defined in the FBO extension. If it's not
available we'll fallback to temporarily enabling
GL_GENERATE_MIPMAP and reuploading the first pixel */
if (cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN))
ctx->texture_driver->gl_generate_mipmaps (ctx, GL_TEXTURE_2D);
Dynamically load the GL or GLES library The GL or GLES library is now dynamically loaded by the CoglRenderer so that it can choose between GL, GLES1 and GLES2 at runtime. The library is loaded by the renderer because it needs to be done before calling eglInitialize. There is a new environment variable called COGL_DRIVER to choose between gl, gles1 or gles2. The #ifdefs for HAVE_COGL_GL, HAVE_COGL_GLES and HAVE_COGL_GLES2 have been changed so that they don't assume the ifdefs are mutually exclusive. They haven't been removed entirely so that it's possible to compile the GLES backends without the the enums from the GL headers. When using GLX the winsys additionally dynamically loads libGL because that also contains the GLX API. It can't be linked in directly because that would probably conflict with the GLES API if the EGL is selected. When compiling with EGL support the library links directly to libEGL because it doesn't contain any GL API so it shouldn't have any conflicts. When building for WGL or OSX Cogl still directly links against the GL API so there is a #define in config.h so that Cogl won't try to dlopen the library. Cogl-pango previously had a #ifdef to detect when the GL backend is used so that it can sneakily pass GL_QUADS to cogl_vertex_buffer_draw. This is now changed so that it queries the CoglContext for the backend. However to get this to work Cogl now needs to export the _cogl_context_get_default symbol and cogl-pango needs some extra -I flags to so that it can include cogl-context-private.h
2011-07-07 19:44:56 +00:00
#if defined(HAVE_COGL_GLES) || defined(HAVE_COGL_GL)
else
{
GE( ctx, glTexParameteri (GL_TEXTURE_2D,
GL_GENERATE_MIPMAP,
GL_TRUE) );
GE( ctx, glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, 1, 1,
tex_2d->first_pixel.gl_format,
tex_2d->first_pixel.gl_type,
tex_2d->first_pixel.data) );
GE( ctx, glTexParameteri (GL_TEXTURE_2D,
GL_GENERATE_MIPMAP,
GL_FALSE) );
}
#endif
tex_2d->mipmaps_dirty = FALSE;
}
}
2010-01-18 09:22:04 +00:00
static void
_cogl_texture_2d_ensure_non_quad_rendering (CoglTexture *tex)
{
/* Nothing needs to be done */
}
static gboolean
_cogl_texture_2d_set_region (CoglTexture *tex,
int src_x,
int src_y,
int dst_x,
int dst_y,
unsigned int dst_width,
unsigned int dst_height,
CoglBitmap *bmp)
{
CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex);
GLenum gl_format;
GLenum gl_type;
cogl-bitmap: Encapsulate the CoglBitmap even internally The CoglBitmap struct is now only defined within cogl-bitmap.c so that all of its members can now only be accessed with accessor functions. To get to the data pointer for the bitmap image you must first call _cogl_bitmap_map and later call _cogl_bitmap_unmap. The map function takes the same arguments as cogl_pixel_array_map so that eventually we can make a bitmap optionally internally divert to a pixel array. There is a _cogl_bitmap_new_from_data function which constructs a new bitmap object and takes ownership of the data pointer. The function gets passed a destroy callback which gets called when the bitmap is freed. This is similar to how gdk_pixbuf_new_from_data works. Alternatively NULL can be passed for the destroy function which means that the caller will manage the life of the pointer (but must guarantee that it stays alive at least until the bitmap is freed). This mechanism is used instead of the old approach of creating a CoglBitmap struct on the stack and manually filling in the members. It could also later be used to create a CoglBitmap that owns a GdkPixbuf ref so that we don't necessarily have to copy the GdkPixbuf data when converting to a bitmap. There is also _cogl_bitmap_new_shared. This creates a bitmap using a reference to another CoglBitmap for the data. This is a bit of a hack but it is needed by the atlas texture backend which wants to divert the set_region virtual to another texture but it needs to override the format of the bitmap to ignore the premult flag.
2010-07-07 17:44:16 +00:00
guint8 *data;
_COGL_GET_CONTEXT (ctx, FALSE);
bmp = _cogl_texture_prepare_for_upload (bmp,
cogl_texture_get_format (tex),
NULL,
NULL,
&gl_format,
&gl_type);
/* If this touches the first pixel then we'll update our copy */
cogl-bitmap: Encapsulate the CoglBitmap even internally The CoglBitmap struct is now only defined within cogl-bitmap.c so that all of its members can now only be accessed with accessor functions. To get to the data pointer for the bitmap image you must first call _cogl_bitmap_map and later call _cogl_bitmap_unmap. The map function takes the same arguments as cogl_pixel_array_map so that eventually we can make a bitmap optionally internally divert to a pixel array. There is a _cogl_bitmap_new_from_data function which constructs a new bitmap object and takes ownership of the data pointer. The function gets passed a destroy callback which gets called when the bitmap is freed. This is similar to how gdk_pixbuf_new_from_data works. Alternatively NULL can be passed for the destroy function which means that the caller will manage the life of the pointer (but must guarantee that it stays alive at least until the bitmap is freed). This mechanism is used instead of the old approach of creating a CoglBitmap struct on the stack and manually filling in the members. It could also later be used to create a CoglBitmap that owns a GdkPixbuf ref so that we don't necessarily have to copy the GdkPixbuf data when converting to a bitmap. There is also _cogl_bitmap_new_shared. This creates a bitmap using a reference to another CoglBitmap for the data. This is a bit of a hack but it is needed by the atlas texture backend which wants to divert the set_region virtual to another texture but it needs to override the format of the bitmap to ignore the premult flag.
2010-07-07 17:44:16 +00:00
if (dst_x == 0 && dst_y == 0 &&
!cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN) &&
cogl-bitmap: Encapsulate the CoglBitmap even internally The CoglBitmap struct is now only defined within cogl-bitmap.c so that all of its members can now only be accessed with accessor functions. To get to the data pointer for the bitmap image you must first call _cogl_bitmap_map and later call _cogl_bitmap_unmap. The map function takes the same arguments as cogl_pixel_array_map so that eventually we can make a bitmap optionally internally divert to a pixel array. There is a _cogl_bitmap_new_from_data function which constructs a new bitmap object and takes ownership of the data pointer. The function gets passed a destroy callback which gets called when the bitmap is freed. This is similar to how gdk_pixbuf_new_from_data works. Alternatively NULL can be passed for the destroy function which means that the caller will manage the life of the pointer (but must guarantee that it stays alive at least until the bitmap is freed). This mechanism is used instead of the old approach of creating a CoglBitmap struct on the stack and manually filling in the members. It could also later be used to create a CoglBitmap that owns a GdkPixbuf ref so that we don't necessarily have to copy the GdkPixbuf data when converting to a bitmap. There is also _cogl_bitmap_new_shared. This creates a bitmap using a reference to another CoglBitmap for the data. This is a bit of a hack but it is needed by the atlas texture backend which wants to divert the set_region virtual to another texture but it needs to override the format of the bitmap to ignore the premult flag.
2010-07-07 17:44:16 +00:00
(data = _cogl_bitmap_map (bmp, COGL_BUFFER_ACCESS_READ, 0)))
{
cogl-bitmap: Encapsulate the CoglBitmap even internally The CoglBitmap struct is now only defined within cogl-bitmap.c so that all of its members can now only be accessed with accessor functions. To get to the data pointer for the bitmap image you must first call _cogl_bitmap_map and later call _cogl_bitmap_unmap. The map function takes the same arguments as cogl_pixel_array_map so that eventually we can make a bitmap optionally internally divert to a pixel array. There is a _cogl_bitmap_new_from_data function which constructs a new bitmap object and takes ownership of the data pointer. The function gets passed a destroy callback which gets called when the bitmap is freed. This is similar to how gdk_pixbuf_new_from_data works. Alternatively NULL can be passed for the destroy function which means that the caller will manage the life of the pointer (but must guarantee that it stays alive at least until the bitmap is freed). This mechanism is used instead of the old approach of creating a CoglBitmap struct on the stack and manually filling in the members. It could also later be used to create a CoglBitmap that owns a GdkPixbuf ref so that we don't necessarily have to copy the GdkPixbuf data when converting to a bitmap. There is also _cogl_bitmap_new_shared. This creates a bitmap using a reference to another CoglBitmap for the data. This is a bit of a hack but it is needed by the atlas texture backend which wants to divert the set_region virtual to another texture but it needs to override the format of the bitmap to ignore the premult flag.
2010-07-07 17:44:16 +00:00
CoglPixelFormat bpp =
_cogl_pixel_format_get_bytes_per_pixel (cogl_bitmap_get_format (bmp));
tex_2d->first_pixel.gl_format = gl_format;
tex_2d->first_pixel.gl_type = gl_type;
memcpy (tex_2d->first_pixel.data,
data + cogl_bitmap_get_rowstride (bmp) * src_y + bpp * src_x,
bpp);
cogl-bitmap: Encapsulate the CoglBitmap even internally The CoglBitmap struct is now only defined within cogl-bitmap.c so that all of its members can now only be accessed with accessor functions. To get to the data pointer for the bitmap image you must first call _cogl_bitmap_map and later call _cogl_bitmap_unmap. The map function takes the same arguments as cogl_pixel_array_map so that eventually we can make a bitmap optionally internally divert to a pixel array. There is a _cogl_bitmap_new_from_data function which constructs a new bitmap object and takes ownership of the data pointer. The function gets passed a destroy callback which gets called when the bitmap is freed. This is similar to how gdk_pixbuf_new_from_data works. Alternatively NULL can be passed for the destroy function which means that the caller will manage the life of the pointer (but must guarantee that it stays alive at least until the bitmap is freed). This mechanism is used instead of the old approach of creating a CoglBitmap struct on the stack and manually filling in the members. It could also later be used to create a CoglBitmap that owns a GdkPixbuf ref so that we don't necessarily have to copy the GdkPixbuf data when converting to a bitmap. There is also _cogl_bitmap_new_shared. This creates a bitmap using a reference to another CoglBitmap for the data. This is a bit of a hack but it is needed by the atlas texture backend which wants to divert the set_region virtual to another texture but it needs to override the format of the bitmap to ignore the premult flag.
2010-07-07 17:44:16 +00:00
_cogl_bitmap_unmap (bmp);
}
/* Send data to GL */
ctx->texture_driver->upload_subregion_to_gl (ctx,
GL_TEXTURE_2D,
tex_2d->gl_texture,
FALSE,
src_x, src_y,
dst_x, dst_y,
dst_width, dst_height,
bmp,
gl_format,
gl_type);
tex_2d->mipmaps_dirty = TRUE;
cogl_object_unref (bmp);
return TRUE;
}
static gboolean
_cogl_texture_2d_get_data (CoglTexture *tex,
CoglPixelFormat format,
unsigned int rowstride,
guint8 *data)
{
CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex);
cogl: improves header and coding style consistency We've had complaints that our Cogl code/headers are a bit "special" so this is a first pass at tidying things up by giving them some consistency. These changes are all consistent with how new code in Cogl is being written, but the style isn't consistently applied across all code yet. There are two parts to this patch; but since each one required a large amount of effort to maintain tidy indenting it made sense to combine the changes to reduce the time spent re indenting the same lines. The first change is to use a consistent style for declaring function prototypes in headers. Cogl headers now consistently use this style for prototypes: return_type cogl_function_name (CoglType arg0, CoglType arg1); Not everyone likes this style, but it seems that most of the currently active Cogl developers agree on it. The second change is to constrain the use of redundant glib data types in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all been replaced with int, unsigned int, float, long, unsigned long and char respectively. When talking about pixel data; use of guchar has been replaced with guint8, otherwise unsigned char can be used. The glib types that we continue to use for portability are gboolean, gint{8,16,32,64}, guint{8,16,32,64} and gsize. The general intention is that Cogl should look palatable to the widest range of C programmers including those outside the Gnome community so - especially for the public API - we want to minimize the number of foreign looking typedefs.
2010-02-10 01:57:32 +00:00
int bpp;
GLenum gl_format;
GLenum gl_type;
_COGL_GET_CONTEXT (ctx, FALSE);
bpp = _cogl_pixel_format_get_bytes_per_pixel (format);
ctx->driver_vtable->pixel_format_to_gl (ctx,
format,
NULL, /* internal format */
&gl_format,
&gl_type);
ctx->texture_driver->prep_gl_for_pixels_download (ctx,
rowstride,
tex_2d->width,
bpp);
_cogl_bind_gl_texture_transient (GL_TEXTURE_2D,
tex_2d->gl_texture,
tex_2d->is_foreign);
return ctx->texture_driver->gl_get_tex_image (ctx,
GL_TEXTURE_2D,
gl_format,
gl_type,
data);
}
static CoglPixelFormat
_cogl_texture_2d_get_format (CoglTexture *tex)
{
return COGL_TEXTURE_2D (tex)->format;
}
static GLenum
_cogl_texture_2d_get_gl_format (CoglTexture *tex)
{
return COGL_TEXTURE_2D (tex)->gl_format;
}
cogl: improves header and coding style consistency We've had complaints that our Cogl code/headers are a bit "special" so this is a first pass at tidying things up by giving them some consistency. These changes are all consistent with how new code in Cogl is being written, but the style isn't consistently applied across all code yet. There are two parts to this patch; but since each one required a large amount of effort to maintain tidy indenting it made sense to combine the changes to reduce the time spent re indenting the same lines. The first change is to use a consistent style for declaring function prototypes in headers. Cogl headers now consistently use this style for prototypes: return_type cogl_function_name (CoglType arg0, CoglType arg1); Not everyone likes this style, but it seems that most of the currently active Cogl developers agree on it. The second change is to constrain the use of redundant glib data types in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all been replaced with int, unsigned int, float, long, unsigned long and char respectively. When talking about pixel data; use of guchar has been replaced with guint8, otherwise unsigned char can be used. The glib types that we continue to use for portability are gboolean, gint{8,16,32,64}, guint{8,16,32,64} and gsize. The general intention is that Cogl should look palatable to the widest range of C programmers including those outside the Gnome community so - especially for the public API - we want to minimize the number of foreign looking typedefs.
2010-02-10 01:57:32 +00:00
static int
_cogl_texture_2d_get_width (CoglTexture *tex)
{
return COGL_TEXTURE_2D (tex)->width;
}
cogl: improves header and coding style consistency We've had complaints that our Cogl code/headers are a bit "special" so this is a first pass at tidying things up by giving them some consistency. These changes are all consistent with how new code in Cogl is being written, but the style isn't consistently applied across all code yet. There are two parts to this patch; but since each one required a large amount of effort to maintain tidy indenting it made sense to combine the changes to reduce the time spent re indenting the same lines. The first change is to use a consistent style for declaring function prototypes in headers. Cogl headers now consistently use this style for prototypes: return_type cogl_function_name (CoglType arg0, CoglType arg1); Not everyone likes this style, but it seems that most of the currently active Cogl developers agree on it. The second change is to constrain the use of redundant glib data types in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all been replaced with int, unsigned int, float, long, unsigned long and char respectively. When talking about pixel data; use of guchar has been replaced with guint8, otherwise unsigned char can be used. The glib types that we continue to use for portability are gboolean, gint{8,16,32,64}, guint{8,16,32,64} and gsize. The general intention is that Cogl should look palatable to the widest range of C programmers including those outside the Gnome community so - especially for the public API - we want to minimize the number of foreign looking typedefs.
2010-02-10 01:57:32 +00:00
static int
_cogl_texture_2d_get_height (CoglTexture *tex)
{
return COGL_TEXTURE_2D (tex)->height;
}
static gboolean
_cogl_texture_2d_is_foreign (CoglTexture *tex)
{
return COGL_TEXTURE_2D (tex)->is_foreign;
}
static CoglTextureType
_cogl_texture_2d_get_type (CoglTexture *tex)
{
return COGL_TEXTURE_TYPE_2D;
}
static const CoglTextureVtable
cogl_texture_2d_vtable =
{
TRUE, /* primitive */
_cogl_texture_2d_set_region,
_cogl_texture_2d_get_data,
NULL, /* foreach_sub_texture_in_region */
_cogl_texture_2d_get_max_waste,
_cogl_texture_2d_is_sliced,
_cogl_texture_2d_can_hardware_repeat,
_cogl_texture_2d_transform_coords_to_gl,
2010-01-18 09:22:04 +00:00
_cogl_texture_2d_transform_quad_coords_to_gl,
_cogl_texture_2d_get_gl_texture,
_cogl_texture_2d_set_filters,
_cogl_texture_2d_pre_paint,
2010-01-18 09:22:04 +00:00
_cogl_texture_2d_ensure_non_quad_rendering,
_cogl_texture_2d_set_wrap_mode_parameters,
_cogl_texture_2d_get_format,
_cogl_texture_2d_get_gl_format,
_cogl_texture_2d_get_width,
_cogl_texture_2d_get_height,
_cogl_texture_2d_get_type,
_cogl_texture_2d_is_foreign,
_cogl_texture_2d_set_auto_mipmap
};