4
* An object oriented GL/GLES Abstraction/Utility Layer
6
* Copyright (C) 2007,2008,2009,2011,2012 Intel Corporation.
7
* Copyright (C) 2010 Red Hat, Inc.
9
* This library is free software; you can redistribute it and/or
10
* modify it under the terms of the GNU Lesser General Public
11
* License as published by the Free Software Foundation; either
12
* version 2 of the License, or (at your option) any later version.
14
* This library is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
* Lesser General Public License for more details.
19
* You should have received a copy of the GNU Lesser General Public
20
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
25
* Matthew Allum <mallum@openedhand.com>
26
* Neil Roberts <neil@linux.intel.com>
27
* Robert Bragg <robert@linux.intel.com>
34
#include "cogl-context-private.h"
35
#include "cogl-texture.h"
36
#include "cogl-util.h"
37
#include "cogl-texture-2d.h"
38
#include "cogl-primitive-texture.h"
39
#include "cogl-texture-2d-sliced-private.h"
40
#include "cogl-private.h"
41
#include "cogl-object.h"
42
#include "cogl-bitmap-private.h"
43
#include "cogl-atlas-texture-private.h"
44
#include "cogl-error-private.h"
45
#include "cogl-texture-rectangle.h"
46
#include "cogl-sub-texture.h"
47
#include "cogl-texture-2d-gl.h"
50
cogl_texture_new_with_size (unsigned int width,
52
CoglTextureFlags flags,
53
CoglPixelFormat internal_format)
56
CoglError *skip_error = NULL;
58
_COGL_GET_CONTEXT (ctx, NULL);
60
if ((_cogl_util_is_pot (width) && _cogl_util_is_pot (height)) ||
61
(cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_BASIC) &&
62
cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP)))
64
/* First try creating a fast-path non-sliced texture */
65
tex = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx,
69
/* TODO: instead of allocating storage here it would be better
70
* if we had some api that let us just check that the size is
71
* supported by the hardware so storage could be allocated
72
* lazily when uploading data. */
73
if (!cogl_texture_allocate (tex, &skip_error))
75
cogl_error_free (skip_error);
76
cogl_object_unref (tex);
85
CoglBool auto_mipmap = !(flags & COGL_TEXTURE_NO_AUTO_MIPMAP);
86
cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (tex),
91
/* If it fails resort to sliced textures */
92
int max_waste = flags & COGL_TEXTURE_NO_SLICING ? -1 : COGL_TEXTURE_MAX_WASTE;
93
tex = COGL_TEXTURE (cogl_texture_2d_sliced_new_with_size (ctx,
104
_cogl_texture_new_from_data (CoglContext *ctx,
107
CoglTextureFlags flags,
108
CoglPixelFormat format,
109
CoglPixelFormat internal_format,
117
_COGL_RETURN_VAL_IF_FAIL (format != COGL_PIXEL_FORMAT_ANY, NULL);
118
_COGL_RETURN_VAL_IF_FAIL (data != NULL, NULL);
120
/* Rowstride from width if not given */
122
rowstride = width * _cogl_pixel_format_get_bytes_per_pixel (format);
124
/* Wrap the data into a bitmap */
125
bmp = cogl_bitmap_new_for_data (ctx,
131
tex = _cogl_texture_new_from_bitmap (bmp, flags, internal_format, error);
133
cogl_object_unref (bmp);
139
cogl_texture_new_from_data (int width,
141
CoglTextureFlags flags,
142
CoglPixelFormat format,
143
CoglPixelFormat internal_format,
147
CoglError *ignore_error = NULL;
150
_COGL_GET_CONTEXT (ctx, NULL);
152
tex = _cogl_texture_new_from_data (ctx,
155
format, internal_format,
160
cogl_error_free (ignore_error);
165
_cogl_texture_new_from_bitmap (CoglBitmap *bitmap,
166
CoglTextureFlags flags,
167
CoglPixelFormat internal_format,
170
CoglContext *ctx = _cogl_bitmap_get_context (bitmap);
171
CoglAtlasTexture *atlas_tex;
173
CoglError *internal_error = NULL;
175
/* First try putting the texture in the atlas */
176
if ((atlas_tex = _cogl_atlas_texture_new_from_bitmap (bitmap,
180
return COGL_TEXTURE (atlas_tex);
182
if (cogl_error_matches (internal_error,
184
COGL_SYSTEM_ERROR_NO_MEMORY))
186
_cogl_propagate_error (error, internal_error);
190
cogl_error_free (internal_error);
191
internal_error = NULL;
193
/* If that doesn't work try a fast path 2D texture */
194
if ((_cogl_util_is_pot (bitmap->width) &&
195
_cogl_util_is_pot (bitmap->height)) ||
196
(cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_BASIC) &&
197
cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP)))
199
tex = COGL_TEXTURE (cogl_texture_2d_new_from_bitmap (bitmap,
203
if (cogl_error_matches (internal_error,
205
COGL_SYSTEM_ERROR_NO_MEMORY))
207
_cogl_propagate_error (error, internal_error);
213
cogl_error_free (internal_error);
214
internal_error = NULL;
222
CoglBool auto_mipmap = !(flags & COGL_TEXTURE_NO_AUTO_MIPMAP);
223
cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (tex),
228
/* Otherwise create a sliced texture */
229
tex = COGL_TEXTURE (_cogl_texture_2d_sliced_new_from_bitmap (bitmap,
239
cogl_texture_new_from_bitmap (CoglBitmap *bitmap,
240
CoglTextureFlags flags,
241
CoglPixelFormat internal_format)
243
CoglError *ignore_error = NULL;
245
_cogl_texture_new_from_bitmap (bitmap, flags, internal_format,
248
cogl_error_free (ignore_error);
253
cogl_texture_new_from_file (const char *filename,
254
CoglTextureFlags flags,
255
CoglPixelFormat internal_format,
259
CoglTexture *texture = NULL;
260
CoglPixelFormat src_format;
262
_COGL_GET_CONTEXT (ctx, NULL);
264
_COGL_RETURN_VAL_IF_FAIL (error == NULL || *error == NULL, NULL);
266
bmp = cogl_bitmap_new_from_file (filename, error);
270
src_format = cogl_bitmap_get_format (bmp);
272
/* We know that the bitmap data is solely owned by this function so
273
we can do the premult conversion in place. This avoids having to
274
copy the bitmap which will otherwise happen in
275
_cogl_texture_prepare_for_upload */
277
_cogl_texture_determine_internal_format (src_format, internal_format);
278
if (!_cogl_texture_needs_premult_conversion (src_format, internal_format) ||
279
_cogl_bitmap_convert_premult_status (bmp,
280
src_format ^ COGL_PREMULT_BIT,
284
_cogl_texture_new_from_bitmap (bmp, flags, internal_format, error);
287
cogl_object_unref (bmp);
293
cogl_texture_new_from_foreign (GLuint gl_handle,
299
CoglPixelFormat format)
301
_COGL_GET_CONTEXT (ctx, NULL);
304
if (gl_target == GL_TEXTURE_RECTANGLE_ARB)
306
CoglTextureRectangle *texture_rectangle;
307
CoglSubTexture *sub_texture;
309
if (x_pot_waste != 0 || y_pot_waste != 0)
311
/* It shouldn't be necessary to have waste in this case since
312
* the texture isn't limited to power of two sizes. */
313
g_warning ("You can't create a foreign GL_TEXTURE_RECTANGLE cogl "
314
"texture with waste\n");
318
texture_rectangle = cogl_texture_rectangle_new_from_foreign (ctx,
325
/* CoglTextureRectangle textures work with non-normalized
326
* coordinates, but the semantics for this function that people
327
* depend on are that all returned texture works with normalized
328
* coordinates so we wrap with a CoglSubTexture... */
329
sub_texture = cogl_sub_texture_new (ctx,
330
COGL_TEXTURE (texture_rectangle),
331
0, 0, width, height);
332
return COGL_TEXTURE (sub_texture);
336
if (x_pot_waste != 0 || y_pot_waste != 0)
337
return COGL_TEXTURE (_cogl_texture_2d_sliced_new_from_foreign (ctx,
347
return COGL_TEXTURE (cogl_texture_2d_new_from_foreign (ctx,