diff options
Diffstat (limited to 'cogl/cogl/driver/gl/cogl-texture-gl.c')
-rw-r--r-- | cogl/cogl/driver/gl/cogl-texture-gl.c | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/cogl/cogl/driver/gl/cogl-texture-gl.c b/cogl/cogl/driver/gl/cogl-texture-gl.c new file mode 100644 index 000000000..2e281c03b --- /dev/null +++ b/cogl/cogl/driver/gl/cogl-texture-gl.c @@ -0,0 +1,158 @@ +/* + * Cogl + * + * A Low Level GPU Graphics and Utilities API + * + * Copyright (C) 2012 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif + +#include "cogl-context-private.h" +#include "cogl-util-gl-private.h" +#include "cogl-texture-gl-private.h" +#include "cogl-texture-3d-private.h" +#include "cogl-util.h" +#include "cogl-pipeline-opengl-private.h" + +static inline int +calculate_alignment (int rowstride) +{ + int alignment = 1 << (_cogl_util_ffs (rowstride) - 1); + + return MIN (alignment, 8); +} + +void +_cogl_texture_gl_prep_alignment_for_pixels_upload (CoglContext *ctx, + int pixels_rowstride) +{ + GE( ctx, glPixelStorei (GL_UNPACK_ALIGNMENT, + calculate_alignment (pixels_rowstride)) ); +} + +void +_cogl_texture_gl_prep_alignment_for_pixels_download (CoglContext *ctx, + int bpp, + int width, + int rowstride) +{ + int alignment; + + /* If no padding is needed then we can always use an alignment of 1. + * We want to do this even though it is equivalent to the alignment + * of the rowstride because the Intel driver in Mesa currently has + * an optimisation when reading data into a PBO that only works if + * the alignment is exactly 1. + * + * https://bugs.freedesktop.org/show_bug.cgi?id=46632 + */ + + if (rowstride == bpp * width) + alignment = 1; + else + alignment = calculate_alignment (rowstride); + + GE( ctx, glPixelStorei (GL_PACK_ALIGNMENT, alignment) ); +} + +void +_cogl_texture_gl_flush_legacy_texobj_wrap_modes (CoglTexture *texture, + unsigned int wrap_mode_s, + unsigned int wrap_mode_t, + unsigned int wrap_mode_p) +{ + texture->vtable->gl_flush_legacy_texobj_wrap_modes (texture, + wrap_mode_s, + wrap_mode_t, + wrap_mode_p); +} + +void +_cogl_texture_gl_flush_legacy_texobj_filters (CoglTexture *texture, + unsigned int min_filter, + unsigned int mag_filter) +{ + texture->vtable->gl_flush_legacy_texobj_filters (texture, + min_filter, mag_filter); +} + +void +_cogl_texture_gl_maybe_update_max_level (CoglTexture *texture, + int max_level) +{ + /* This isn't supported on GLES */ +#ifdef HAVE_COGL_GL + CoglContext *ctx = texture->context; + + if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL) && + texture->max_level < max_level) + { + CoglContext *ctx = texture->context; + GLuint gl_handle; + GLenum gl_target; + + cogl_texture_get_gl_texture (texture, &gl_handle, &gl_target); + + texture->max_level = max_level; + + _cogl_bind_gl_texture_transient (gl_target, + gl_handle, + _cogl_texture_is_foreign (texture)); + + GE( ctx, glTexParameteri (gl_target, + GL_TEXTURE_MAX_LEVEL, texture->max_level)); + } +#endif /* HAVE_COGL_GL */ +} + +void +_cogl_texture_gl_generate_mipmaps (CoglTexture *texture) +{ + CoglContext *ctx = texture->context; + int n_levels = _cogl_texture_get_n_levels (texture); + GLuint gl_handle; + GLenum gl_target; + + _cogl_texture_gl_maybe_update_max_level (texture, n_levels - 1); + + cogl_texture_get_gl_texture (texture, &gl_handle, &gl_target); + + _cogl_bind_gl_texture_transient (gl_target, + gl_handle, + _cogl_texture_is_foreign (texture)); + GE( ctx, glGenerateMipmap (gl_target) ); +} + +GLenum +_cogl_texture_gl_get_format (CoglTexture *texture) +{ + return texture->vtable->get_gl_format (texture); +} |