1 /*
2 * Cogl
3 *
4 * A Low Level GPU Graphics and Utilities API
5 *
6 * Copyright (C) 2012 Intel Corporation.
7 *
8 * Permission is hereby granted, free of charge, to any person
9 * obtaining a copy of this software and associated documentation
10 * files (the "Software"), to deal in the Software without
11 * restriction, including without limitation the rights to use, copy,
12 * modify, merge, publish, distribute, sublicense, and/or sell copies
13 * of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be
17 * included in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
23 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
24 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 *
28 */
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #ifdef HAVE_STRINGS_H
35 #include <strings.h>
36 #endif
37
38 #include "cogl-context-private.h"
39 #include "cogl-util-gl-private.h"
40 #include "cogl-texture-gl-private.h"
41 #include "cogl-texture-3d-private.h"
42 #include "cogl-util.h"
43 #include "cogl-pipeline-opengl-private.h"
44
45 static inline int
calculate_alignment(int rowstride)46 calculate_alignment (int rowstride)
47 {
48 int alignment = 1 << (_cogl_util_ffs (rowstride) - 1);
49
50 return MIN (alignment, 8);
51 }
52
53 void
_cogl_texture_gl_prep_alignment_for_pixels_upload(CoglContext * ctx,int pixels_rowstride)54 _cogl_texture_gl_prep_alignment_for_pixels_upload (CoglContext *ctx,
55 int pixels_rowstride)
56 {
57 GE( ctx, glPixelStorei (GL_UNPACK_ALIGNMENT,
58 calculate_alignment (pixels_rowstride)) );
59 }
60
61 void
_cogl_texture_gl_prep_alignment_for_pixels_download(CoglContext * ctx,int bpp,int width,int rowstride)62 _cogl_texture_gl_prep_alignment_for_pixels_download (CoglContext *ctx,
63 int bpp,
64 int width,
65 int rowstride)
66 {
67 int alignment;
68
69 /* If no padding is needed then we can always use an alignment of 1.
70 * We want to do this even though it is equivalent to the alignment
71 * of the rowstride because the Intel driver in Mesa currently has
72 * an optimisation when reading data into a PBO that only works if
73 * the alignment is exactly 1.
74 *
75 * https://bugs.freedesktop.org/show_bug.cgi?id=46632
76 */
77
78 if (rowstride == bpp * width)
79 alignment = 1;
80 else
81 alignment = calculate_alignment (rowstride);
82
83 GE( ctx, glPixelStorei (GL_PACK_ALIGNMENT, alignment) );
84 }
85
86 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)87 _cogl_texture_gl_flush_legacy_texobj_wrap_modes (CoglTexture *texture,
88 unsigned int wrap_mode_s,
89 unsigned int wrap_mode_t,
90 unsigned int wrap_mode_p)
91 {
92 texture->vtable->gl_flush_legacy_texobj_wrap_modes (texture,
93 wrap_mode_s,
94 wrap_mode_t,
95 wrap_mode_p);
96 }
97
98 void
_cogl_texture_gl_flush_legacy_texobj_filters(CoglTexture * texture,unsigned int min_filter,unsigned int mag_filter)99 _cogl_texture_gl_flush_legacy_texobj_filters (CoglTexture *texture,
100 unsigned int min_filter,
101 unsigned int mag_filter)
102 {
103 texture->vtable->gl_flush_legacy_texobj_filters (texture,
104 min_filter, mag_filter);
105 }
106
107 void
_cogl_texture_gl_maybe_update_max_level(CoglTexture * texture,int max_level)108 _cogl_texture_gl_maybe_update_max_level (CoglTexture *texture,
109 int max_level)
110 {
111 /* This isn't supported on GLES */
112 #ifdef HAVE_COGL_GL
113 CoglContext *ctx = texture->context;
114
115 if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL) &&
116 texture->max_level < max_level)
117 {
118 CoglContext *ctx = texture->context;
119 GLuint gl_handle;
120 GLenum gl_target;
121
122 cogl_texture_get_gl_texture (texture, &gl_handle, &gl_target);
123
124 texture->max_level = max_level;
125
126 _cogl_bind_gl_texture_transient (gl_target,
127 gl_handle,
128 _cogl_texture_is_foreign (texture));
129
130 GE( ctx, glTexParameteri (gl_target,
131 GL_TEXTURE_MAX_LEVEL, texture->max_level));
132 }
133 #endif /* HAVE_COGL_GL */
134 }
135
136 void
_cogl_texture_gl_generate_mipmaps(CoglTexture * texture)137 _cogl_texture_gl_generate_mipmaps (CoglTexture *texture)
138 {
139 CoglContext *ctx = texture->context;
140 int n_levels = _cogl_texture_get_n_levels (texture);
141 GLuint gl_handle;
142 GLenum gl_target;
143
144 _cogl_texture_gl_maybe_update_max_level (texture, n_levels - 1);
145
146 cogl_texture_get_gl_texture (texture, &gl_handle, &gl_target);
147
148 _cogl_bind_gl_texture_transient (gl_target,
149 gl_handle,
150 _cogl_texture_is_foreign (texture));
151 GE( ctx, glGenerateMipmap (gl_target) );
152 }
153
154 GLenum
_cogl_texture_gl_get_format(CoglTexture * texture)155 _cogl_texture_gl_get_format (CoglTexture *texture)
156 {
157 return texture->vtable->get_gl_format (texture);
158 }
159