~noskcaj/ubuntu/trusty/cogl/1.16.2

« back to all changes in this revision

Viewing changes to cogl/cogl-auto-texture.c

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha, Jeremy Bicha, Rico Tzschichholz
  • Date: 2013-02-26 16:43:25 UTC
  • mfrom: (1.1.10)
  • Revision ID: package-import@ubuntu.com-20130226164325-t4z9rylpa20v0p6q
Tags: 1.13.4-0ubuntu1
[ Jeremy Bicha ]
* New upstream release
  - soname bump
* debian/control.in:
  - Bump minimum glib to 2.32
  - Drop obsolete breaks/replaces
  - Bump libclutter-1.0-dev breaks for soname transition
* debian/libcogl-dev.install:
  - Add some missing files

[ Rico Tzschichholz ]
* debian/control.in:
  - Build-depend on libxrandr-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Cogl
 
3
 *
 
4
 * An object oriented GL/GLES Abstraction/Utility Layer
 
5
 *
 
6
 * Copyright (C) 2007,2008,2009,2011,2012 Intel Corporation.
 
7
 * Copyright (C) 2010 Red Hat, Inc.
 
8
 *
 
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.
 
13
 *
 
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.
 
18
 *
 
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/>.
 
21
 *
 
22
 *
 
23
 *
 
24
 * Authors:
 
25
 *  Matthew Allum  <mallum@openedhand.com>
 
26
 *  Neil Roberts   <neil@linux.intel.com>
 
27
 *  Robert Bragg   <robert@linux.intel.com>
 
28
 */
 
29
 
 
30
#ifdef HAVE_CONFIG_H
 
31
#include "config.h"
 
32
#endif
 
33
 
 
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"
 
48
 
 
49
CoglTexture *
 
50
cogl_texture_new_with_size (unsigned int width,
 
51
                            unsigned int height,
 
52
                            CoglTextureFlags flags,
 
53
                            CoglPixelFormat internal_format)
 
54
{
 
55
  CoglTexture *tex;
 
56
  CoglError *skip_error = NULL;
 
57
 
 
58
  _COGL_GET_CONTEXT (ctx, NULL);
 
59
 
 
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)))
 
63
    {
 
64
      /* First try creating a fast-path non-sliced texture */
 
65
      tex = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx,
 
66
                                                         width, height,
 
67
                                                         internal_format));
 
68
 
 
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))
 
74
        {
 
75
          cogl_error_free (skip_error);
 
76
          cogl_object_unref (tex);
 
77
          tex = NULL;
 
78
        }
 
79
    }
 
80
  else
 
81
    tex = NULL;
 
82
 
 
83
  if (tex)
 
84
    {
 
85
      CoglBool auto_mipmap = !(flags & COGL_TEXTURE_NO_AUTO_MIPMAP);
 
86
      cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (tex),
 
87
                                              auto_mipmap);
 
88
    }
 
89
  else
 
90
    {
 
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,
 
94
                                                                width,
 
95
                                                                height,
 
96
                                                                max_waste,
 
97
                                                                internal_format));
 
98
    }
 
99
 
 
100
  return tex;
 
101
}
 
102
 
 
103
static CoglTexture *
 
104
_cogl_texture_new_from_data (CoglContext *ctx,
 
105
                             int width,
 
106
                             int height,
 
107
                             CoglTextureFlags flags,
 
108
                             CoglPixelFormat format,
 
109
                             CoglPixelFormat internal_format,
 
110
                             int rowstride,
 
111
                             const uint8_t *data,
 
112
                             CoglError **error)
 
113
{
 
114
  CoglBitmap *bmp;
 
115
  CoglTexture *tex;
 
116
 
 
117
  _COGL_RETURN_VAL_IF_FAIL (format != COGL_PIXEL_FORMAT_ANY, NULL);
 
118
  _COGL_RETURN_VAL_IF_FAIL (data != NULL, NULL);
 
119
 
 
120
  /* Rowstride from width if not given */
 
121
  if (rowstride == 0)
 
122
    rowstride = width * _cogl_pixel_format_get_bytes_per_pixel (format);
 
123
 
 
124
  /* Wrap the data into a bitmap */
 
125
  bmp = cogl_bitmap_new_for_data (ctx,
 
126
                                  width, height,
 
127
                                  format,
 
128
                                  rowstride,
 
129
                                  (uint8_t *) data);
 
130
 
 
131
  tex = _cogl_texture_new_from_bitmap (bmp, flags, internal_format, error);
 
132
 
 
133
  cogl_object_unref (bmp);
 
134
 
 
135
  return tex;
 
136
}
 
137
 
 
138
CoglTexture *
 
139
cogl_texture_new_from_data (int width,
 
140
                            int height,
 
141
                            CoglTextureFlags flags,
 
142
                            CoglPixelFormat format,
 
143
                            CoglPixelFormat internal_format,
 
144
                            int rowstride,
 
145
                            const uint8_t *data)
 
146
{
 
147
  CoglError *ignore_error = NULL;
 
148
  CoglTexture *tex;
 
149
 
 
150
  _COGL_GET_CONTEXT (ctx, NULL);
 
151
 
 
152
  tex = _cogl_texture_new_from_data (ctx,
 
153
                                     width, height,
 
154
                                     flags,
 
155
                                     format, internal_format,
 
156
                                     rowstride,
 
157
                                     data,
 
158
                                     &ignore_error);
 
159
  if (!tex)
 
160
    cogl_error_free (ignore_error);
 
161
  return tex;
 
162
}
 
163
 
 
164
CoglTexture *
 
165
_cogl_texture_new_from_bitmap (CoglBitmap *bitmap,
 
166
                               CoglTextureFlags flags,
 
167
                               CoglPixelFormat internal_format,
 
168
                               CoglError **error)
 
169
{
 
170
  CoglContext *ctx = _cogl_bitmap_get_context (bitmap);
 
171
  CoglAtlasTexture *atlas_tex;
 
172
  CoglTexture *tex;
 
173
  CoglError *internal_error = NULL;
 
174
 
 
175
  /* First try putting the texture in the atlas */
 
176
  if ((atlas_tex = _cogl_atlas_texture_new_from_bitmap (bitmap,
 
177
                                                        flags,
 
178
                                                        internal_format,
 
179
                                                        &internal_error)))
 
180
    return COGL_TEXTURE (atlas_tex);
 
181
 
 
182
  if (cogl_error_matches (internal_error,
 
183
                          COGL_SYSTEM_ERROR,
 
184
                          COGL_SYSTEM_ERROR_NO_MEMORY))
 
185
    {
 
186
      _cogl_propagate_error (error, internal_error);
 
187
      return NULL;
 
188
    }
 
189
 
 
190
  cogl_error_free (internal_error);
 
191
  internal_error = NULL;
 
192
 
 
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)))
 
198
    {
 
199
      tex = COGL_TEXTURE (cogl_texture_2d_new_from_bitmap (bitmap,
 
200
                                                           internal_format,
 
201
                                                           &internal_error));
 
202
 
 
203
      if (cogl_error_matches (internal_error,
 
204
                              COGL_SYSTEM_ERROR,
 
205
                              COGL_SYSTEM_ERROR_NO_MEMORY))
 
206
        {
 
207
          _cogl_propagate_error (error, internal_error);
 
208
          return NULL;
 
209
        }
 
210
 
 
211
      if (!tex)
 
212
        {
 
213
          cogl_error_free (internal_error);
 
214
          internal_error = NULL;
 
215
        }
 
216
    }
 
217
  else
 
218
    tex = NULL;
 
219
 
 
220
  if (tex)
 
221
    {
 
222
      CoglBool auto_mipmap = !(flags & COGL_TEXTURE_NO_AUTO_MIPMAP);
 
223
      cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (tex),
 
224
                                              auto_mipmap);
 
225
    }
 
226
  else
 
227
    {
 
228
      /* Otherwise create a sliced texture */
 
229
      tex = COGL_TEXTURE (_cogl_texture_2d_sliced_new_from_bitmap (bitmap,
 
230
                                                             flags,
 
231
                                                             internal_format,
 
232
                                                             error));
 
233
    }
 
234
 
 
235
  return tex;
 
236
}
 
237
 
 
238
CoglTexture *
 
239
cogl_texture_new_from_bitmap (CoglBitmap *bitmap,
 
240
                              CoglTextureFlags flags,
 
241
                              CoglPixelFormat internal_format)
 
242
{
 
243
  CoglError *ignore_error = NULL;
 
244
  CoglTexture *tex =
 
245
    _cogl_texture_new_from_bitmap (bitmap, flags, internal_format,
 
246
                                   &ignore_error);
 
247
  if (!tex)
 
248
    cogl_error_free (ignore_error);
 
249
  return tex;
 
250
}
 
251
 
 
252
CoglTexture *
 
253
cogl_texture_new_from_file (const char        *filename,
 
254
                            CoglTextureFlags   flags,
 
255
                            CoglPixelFormat    internal_format,
 
256
                            CoglError           **error)
 
257
{
 
258
  CoglBitmap *bmp;
 
259
  CoglTexture *texture = NULL;
 
260
  CoglPixelFormat src_format;
 
261
 
 
262
  _COGL_GET_CONTEXT (ctx, NULL);
 
263
 
 
264
  _COGL_RETURN_VAL_IF_FAIL (error == NULL || *error == NULL, NULL);
 
265
 
 
266
  bmp = cogl_bitmap_new_from_file (filename, error);
 
267
  if (bmp == NULL)
 
268
    return NULL;
 
269
 
 
270
  src_format = cogl_bitmap_get_format (bmp);
 
271
 
 
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 */
 
276
  internal_format =
 
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,
 
281
                                           error))
 
282
    {
 
283
      texture =
 
284
        _cogl_texture_new_from_bitmap (bmp, flags, internal_format, error);
 
285
    }
 
286
 
 
287
  cogl_object_unref (bmp);
 
288
 
 
289
  return texture;
 
290
}
 
291
 
 
292
CoglTexture *
 
293
cogl_texture_new_from_foreign (GLuint           gl_handle,
 
294
                               GLenum           gl_target,
 
295
                               GLuint           width,
 
296
                               GLuint           height,
 
297
                               GLuint           x_pot_waste,
 
298
                               GLuint           y_pot_waste,
 
299
                               CoglPixelFormat  format)
 
300
{
 
301
  _COGL_GET_CONTEXT (ctx, NULL);
 
302
 
 
303
#ifdef HAVE_COGL_GL
 
304
  if (gl_target == GL_TEXTURE_RECTANGLE_ARB)
 
305
    {
 
306
      CoglTextureRectangle *texture_rectangle;
 
307
      CoglSubTexture *sub_texture;
 
308
 
 
309
      if (x_pot_waste != 0 || y_pot_waste != 0)
 
310
        {
 
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");
 
315
          return NULL;
 
316
        }
 
317
 
 
318
      texture_rectangle = cogl_texture_rectangle_new_from_foreign (ctx,
 
319
                                                                   gl_handle,
 
320
                                                                   width,
 
321
                                                                   height,
 
322
                                                                   format,
 
323
                                                                   NULL);
 
324
 
 
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);
 
333
    }
 
334
#endif
 
335
 
 
336
  if (x_pot_waste != 0 || y_pot_waste != 0)
 
337
    return COGL_TEXTURE (_cogl_texture_2d_sliced_new_from_foreign (ctx,
 
338
                                                                   gl_handle,
 
339
                                                                   gl_target,
 
340
                                                                   width,
 
341
                                                                   height,
 
342
                                                                   x_pot_waste,
 
343
                                                                   y_pot_waste,
 
344
                                                                   format,
 
345
                                                                   NULL));
 
346
  else
 
347
    return COGL_TEXTURE (cogl_texture_2d_new_from_foreign (ctx,
 
348
                                                           gl_handle,
 
349
                                                           width,
 
350
                                                           height,
 
351
                                                           format,
 
352
                                                           NULL));
 
353
}