~oem-solutions-group/unity-2d/clutter-1.0

« back to all changes in this revision

Viewing changes to clutter/cogl/cogl/driver/gles/cogl-texture-driver.c

  • Committer: Bazaar Package Importer
  • Author(s): Emilio Pozuelo Monfort
  • Date: 2010-03-21 13:27:56 UTC
  • mto: (2.1.3 experimental)
  • mto: This revision was merged to the branch mainline in revision 8.
  • Revision ID: james.westby@ubuntu.com-20100321132756-nf8yd30yxo3zzwcm
Tags: upstream-1.2.2
ImportĀ upstreamĀ versionĀ 1.2.2

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 Intel Corporation.
 
7
 *
 
8
 * This library is free software; you can redistribute it and/or
 
9
 * modify it under the terms of the GNU Lesser General Public
 
10
 * License as published by the Free Software Foundation; either
 
11
 * version 2 of the License, or (at your option) any later version.
 
12
 *
 
13
 * This library is distributed in the hope that it will be useful,
 
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
16
 * Lesser General Public License for more details.
 
17
 *
 
18
 * You should have received a copy of the GNU Lesser General Public
 
19
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 
20
 *
 
21
 *
 
22
 *
 
23
 * Authors:
 
24
 *  Matthew Allum  <mallum@openedhand.com>
 
25
 *  Neil Roberts   <neil@linux.intel.com>
 
26
 *  Robert Bragg   <robert@linux.intel.com>
 
27
 */
 
28
 
 
29
#ifdef HAVE_CONFIG_H
 
30
#include "config.h"
 
31
#endif
 
32
 
 
33
#include "cogl.h"
 
34
#include "cogl-internal.h"
 
35
#include "cogl-util.h"
 
36
#include "cogl-bitmap.h"
 
37
#include "cogl-bitmap-private.h"
 
38
#include "cogl-texture-private.h"
 
39
#include "cogl-material.h"
 
40
#include "cogl-context.h"
 
41
#include "cogl-handle.h"
 
42
#include "cogl-primitives.h"
 
43
 
 
44
#include <string.h>
 
45
#include <stdlib.h>
 
46
#include <math.h>
 
47
 
 
48
#include "cogl-gles2-wrapper.h"
 
49
 
 
50
void
 
51
_cogl_texture_driver_gen (GLenum   gl_target,
 
52
                          GLsizei  n,
 
53
                          GLuint  *textures)
 
54
{
 
55
  unsigned int i;
 
56
 
 
57
  GE (glGenTextures (n, textures));
 
58
 
 
59
  for (i = 0; i < n; i++)
 
60
    {
 
61
      GE (glBindTexture (gl_target, textures[i]));
 
62
 
 
63
      switch (gl_target)
 
64
        {
 
65
      case GL_TEXTURE_2D:
 
66
        /* GL_TEXTURE_MAG_FILTER defaults to GL_LINEAR, no need to set it */
 
67
        GE( glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) );
 
68
        break;
 
69
 
 
70
      default:
 
71
        g_assert_not_reached();
 
72
        }
 
73
 
 
74
    }
 
75
}
 
76
 
 
77
void
 
78
_cogl_texture_driver_prep_gl_for_pixels_upload (int pixels_rowstride,
 
79
                                                int pixels_bpp)
 
80
{
 
81
  _cogl_texture_prep_gl_alignment_for_pixels_upload (pixels_rowstride);
 
82
}
 
83
 
 
84
void
 
85
_cogl_texture_driver_prep_gl_for_pixels_download (int pixels_rowstride,
 
86
                                                  int pixels_bpp)
 
87
{
 
88
  _cogl_texture_prep_gl_alignment_for_pixels_download (pixels_rowstride);
 
89
}
 
90
 
 
91
void
 
92
_cogl_texture_driver_upload_subregion_to_gl (GLenum       gl_target,
 
93
                                             GLuint       gl_handle,
 
94
                                             int          src_x,
 
95
                                             int          src_y,
 
96
                                             int          dst_x,
 
97
                                             int          dst_y,
 
98
                                             int          width,
 
99
                                             int          height,
 
100
                                             CoglBitmap  *source_bmp,
 
101
                                             GLuint       source_gl_format,
 
102
                                             GLuint       source_gl_type)
 
103
{
 
104
  int bpp = _cogl_get_format_bpp (source_bmp->format);
 
105
  CoglBitmap slice_bmp;
 
106
 
 
107
  /* NB: GLES doesn't support the GL_UNPACK_ROW_LENGTH, GL_UNPACK_SKIP_PIXELS
 
108
   * or GL_UNPACK_SKIP_ROWS pixel store options so we can't directly source a
 
109
   * sub-region from source_bmp, we need to use a transient bitmap instead. */
 
110
 
 
111
  /* FIXME: optimize by not copying to intermediate slice bitmap when source
 
112
   * rowstride = bpp * width and the texture image is not sliced */
 
113
 
 
114
  /* Setup temp bitmap for slice subregion */
 
115
  slice_bmp.format = source_bmp->format;
 
116
  slice_bmp.width  = width;
 
117
  slice_bmp.height = height;
 
118
  slice_bmp.rowstride = bpp * slice_bmp.width;
 
119
  slice_bmp.data = g_malloc (slice_bmp.rowstride * slice_bmp.height);
 
120
 
 
121
  /* Setup gl alignment to match rowstride and top-left corner */
 
122
  _cogl_texture_driver_prep_gl_for_pixels_upload (slice_bmp.rowstride,
 
123
                                                  bpp);
 
124
 
 
125
  /* Copy subregion data */
 
126
  _cogl_bitmap_copy_subregion (source_bmp,
 
127
                               &slice_bmp,
 
128
                               src_x,
 
129
                               src_y,
 
130
                               0, 0,
 
131
                               slice_bmp.width,
 
132
                               slice_bmp.height);
 
133
 
 
134
  GE( glBindTexture (gl_target, gl_handle) );
 
135
 
 
136
  GE( glTexSubImage2D (gl_target, 0,
 
137
                       dst_x, dst_y,
 
138
                       width, height,
 
139
                       source_gl_format,
 
140
                       source_gl_type,
 
141
                       slice_bmp.data) );
 
142
 
 
143
  /* Free temp bitmap */
 
144
  g_free (slice_bmp.data);
 
145
}
 
146
 
 
147
void
 
148
_cogl_texture_driver_upload_to_gl (GLenum       gl_target,
 
149
                                   GLuint       gl_handle,
 
150
                                   CoglBitmap  *source_bmp,
 
151
                                   GLint        internal_gl_format,
 
152
                                   GLuint       source_gl_format,
 
153
                                   GLuint       source_gl_type)
 
154
{
 
155
  int bpp = _cogl_get_format_bpp (source_bmp->format);
 
156
  CoglBitmap bmp = *source_bmp;
 
157
  gboolean bmp_owner = FALSE;
 
158
 
 
159
  /* If the rowstride can't be specified with just GL_ALIGNMENT alone
 
160
     then we need to copy the bitmap because there is no GL_ROW_LENGTH */
 
161
  if (source_bmp->rowstride / bpp != source_bmp->width)
 
162
    {
 
163
      bmp.rowstride = bpp * bmp.width;
 
164
      bmp.data = g_malloc (bmp.rowstride * bmp.height);
 
165
      bmp_owner = TRUE;
 
166
 
 
167
      _cogl_bitmap_copy_subregion (source_bmp,
 
168
                                   &bmp,
 
169
                                   0, 0, 0, 0,
 
170
                                   bmp.width,
 
171
                                   bmp.height);
 
172
    }
 
173
 
 
174
  /* Setup gl alignment to match rowstride and top-left corner */
 
175
  _cogl_texture_driver_prep_gl_for_pixels_upload (bmp.rowstride,
 
176
                                                  bpp);
 
177
 
 
178
  GE( glBindTexture (gl_target, gl_handle) );
 
179
 
 
180
  GE( glTexImage2D (gl_target, 0,
 
181
                    internal_gl_format,
 
182
                    bmp.width, bmp.height,
 
183
                    0,
 
184
                    source_gl_format,
 
185
                    source_gl_type,
 
186
                    bmp.data) );
 
187
 
 
188
  if (bmp_owner)
 
189
    g_free (bmp.data);
 
190
}
 
191
 
 
192
/* NB: GLES doesn't support glGetTexImage2D, so cogl-texture will instead
 
193
 * fallback to a generic render + readpixels approach to downloading
 
194
 * texture data. (See _cogl_texture_draw_and_read() ) */
 
195
gboolean
 
196
_cogl_texture_driver_gl_get_tex_image (GLenum  gl_target,
 
197
                                       GLenum  dest_gl_format,
 
198
                                       GLenum  dest_gl_type,
 
199
                                       guint8 *dest)
 
200
{
 
201
  return FALSE;
 
202
}
 
203
 
 
204
gboolean
 
205
_cogl_texture_driver_size_supported (GLenum gl_target,
 
206
                                     GLenum gl_format,
 
207
                                     GLenum gl_type,
 
208
                                     int    width,
 
209
                                     int    height)
 
210
{
 
211
  return TRUE;
 
212
}
 
213
 
 
214
void
 
215
_cogl_texture_driver_try_setting_gl_border_color (
 
216
                                              GLuint   gl_target,
 
217
                                              const GLfloat *transparent_color)
 
218
{
 
219
  /* FAIL! */
 
220
}
 
221
 
 
222
gboolean
 
223
_cogl_pixel_format_from_gl_internal (GLenum            gl_int_format,
 
224
                                     CoglPixelFormat  *out_format)
 
225
{
 
226
  return TRUE;
 
227
}
 
228
 
 
229
CoglPixelFormat
 
230
_cogl_pixel_format_to_gl (CoglPixelFormat  format,
 
231
                          GLenum          *out_glintformat,
 
232
                          GLenum          *out_glformat,
 
233
                          GLenum          *out_gltype)
 
234
{
 
235
  CoglPixelFormat required_format;
 
236
  GLenum          glintformat = 0;
 
237
  GLenum          glformat = 0;
 
238
  GLenum          gltype = 0;
 
239
 
 
240
  /* FIXME: check YUV support */
 
241
 
 
242
  required_format = format;
 
243
 
 
244
  /* Find GL equivalents */
 
245
  switch (format & COGL_UNPREMULT_MASK)
 
246
    {
 
247
    case COGL_PIXEL_FORMAT_A_8:
 
248
      glintformat = GL_ALPHA;
 
249
      glformat = GL_ALPHA;
 
250
      gltype = GL_UNSIGNED_BYTE;
 
251
      break;
 
252
    case COGL_PIXEL_FORMAT_G_8:
 
253
      glintformat = GL_LUMINANCE;
 
254
      glformat = GL_LUMINANCE;
 
255
      gltype = GL_UNSIGNED_BYTE;
 
256
      break;
 
257
 
 
258
      /* Just one 24-bit ordering supported */
 
259
    case COGL_PIXEL_FORMAT_RGB_888:
 
260
    case COGL_PIXEL_FORMAT_BGR_888:
 
261
      glintformat = GL_RGB;
 
262
      glformat = GL_RGB;
 
263
      gltype = GL_UNSIGNED_BYTE;
 
264
      required_format = COGL_PIXEL_FORMAT_RGB_888;
 
265
      break;
 
266
 
 
267
      /* Just one 32-bit ordering supported */
 
268
    case COGL_PIXEL_FORMAT_RGBA_8888:
 
269
    case COGL_PIXEL_FORMAT_BGRA_8888:
 
270
    case COGL_PIXEL_FORMAT_ARGB_8888:
 
271
    case COGL_PIXEL_FORMAT_ABGR_8888:
 
272
      glintformat = GL_RGBA;
 
273
      glformat = GL_RGBA;
 
274
      gltype = GL_UNSIGNED_BYTE;
 
275
      required_format = COGL_PIXEL_FORMAT_RGBA_8888;
 
276
      required_format |= (format & COGL_PREMULT_BIT);
 
277
      break;
 
278
 
 
279
      /* The following three types of channel ordering
 
280
       * are always defined using system word byte
 
281
       * ordering (even according to GLES spec) */
 
282
    case COGL_PIXEL_FORMAT_RGB_565:
 
283
      glintformat = GL_RGB;
 
284
      glformat = GL_RGB;
 
285
      gltype = GL_UNSIGNED_SHORT_5_6_5;
 
286
      break;
 
287
    case COGL_PIXEL_FORMAT_RGBA_4444:
 
288
      glintformat = GL_RGBA;
 
289
      glformat = GL_RGBA;
 
290
      gltype = GL_UNSIGNED_SHORT_4_4_4_4;
 
291
      break;
 
292
    case COGL_PIXEL_FORMAT_RGBA_5551:
 
293
      glintformat = GL_RGBA;
 
294
      glformat = GL_RGBA;
 
295
      gltype = GL_UNSIGNED_SHORT_5_5_5_1;
 
296
      break;
 
297
 
 
298
      /* FIXME: check extensions for YUV support */
 
299
    default:
 
300
      break;
 
301
    }
 
302
 
 
303
  if (out_glintformat != NULL)
 
304
    *out_glintformat = glintformat;
 
305
  if (out_glformat != NULL)
 
306
    *out_glformat = glformat;
 
307
  if (out_gltype != NULL)
 
308
    *out_gltype = gltype;
 
309
 
 
310
  return required_format;
 
311
}
 
312
 
 
313
gboolean
 
314
_cogl_texture_driver_allows_foreign_gl_target (GLenum gl_target)
 
315
{
 
316
  /* Allow 2-dimensional textures only */
 
317
  if (gl_target != GL_TEXTURE_2D)
 
318
    return FALSE;
 
319
  return TRUE;
 
320
}
 
321
 
 
322
void
 
323
_cogl_texture_driver_gl_generate_mipmaps (GLenum gl_target)
 
324
{
 
325
  GE( cogl_wrap_glGenerateMipmap (gl_target) );
 
326
}
 
327
 
 
328
CoglPixelFormat
 
329
_cogl_texture_driver_find_best_gl_get_data_format (
 
330
                                             CoglPixelFormat  format,
 
331
                                             GLenum          *closest_gl_format,
 
332
                                             GLenum          *closest_gl_type)
 
333
{
 
334
  /* Find closest format that's supported by GL
 
335
     (Can't use _cogl_pixel_format_to_gl since available formats
 
336
      when reading pixels on GLES are severely limited) */
 
337
  *closest_gl_format = GL_RGBA;
 
338
  *closest_gl_type = GL_UNSIGNED_BYTE;
 
339
  return COGL_PIXEL_FORMAT_RGBA_8888;
 
340
}
 
341