~gnome3-team/mutter/trunk

« back to all changes in this revision

Viewing changes to cogl/cogl/cogl-indices.c

  • Committer: Rui Matos
  • Date: 2016-04-27 16:36:25 UTC
  • mfrom: (0.87.3184)
  • Revision ID: git-v1:3fcbe1d3ec5c9208dde080f7e9dac24e4c379bc0
Merge cogl's cogl-1.22 branch into mutter

https://bugzilla.gnome.org/show_bug.cgi?id=760439

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Cogl
 
3
 *
 
4
 * A Low Level GPU Graphics and Utilities API
 
5
 *
 
6
 * Copyright (C) 2010 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
 * Authors:
 
31
 *   Robert Bragg <robert@linux.intel.com>
 
32
 *   Neil Roberts <neil@linux.intel.com>
 
33
 */
 
34
 
 
35
#ifdef HAVE_CONFIG_H
 
36
#include "config.h"
 
37
#endif
 
38
 
 
39
#include "cogl-util.h"
 
40
#include "cogl-object-private.h"
 
41
#include "cogl-context-private.h"
 
42
#include "cogl-indices.h"
 
43
#include "cogl-indices-private.h"
 
44
#include "cogl-index-buffer.h"
 
45
#include "cogl-gtype-private.h"
 
46
 
 
47
#include <stdarg.h>
 
48
 
 
49
static void _cogl_indices_free (CoglIndices *indices);
 
50
 
 
51
COGL_OBJECT_DEFINE (Indices, indices);
 
52
COGL_GTYPE_DEFINE_CLASS (Indices, indices);
 
53
 
 
54
static size_t
 
55
sizeof_indices_type (CoglIndicesType type)
 
56
{
 
57
  switch (type)
 
58
    {
 
59
    case COGL_INDICES_TYPE_UNSIGNED_BYTE:
 
60
      return 1;
 
61
    case COGL_INDICES_TYPE_UNSIGNED_SHORT:
 
62
      return 2;
 
63
    case COGL_INDICES_TYPE_UNSIGNED_INT:
 
64
      return 4;
 
65
    }
 
66
  g_return_val_if_reached (0);
 
67
}
 
68
 
 
69
CoglIndices *
 
70
cogl_indices_new_for_buffer (CoglIndicesType type,
 
71
                             CoglIndexBuffer *buffer,
 
72
                             size_t offset)
 
73
{
 
74
  CoglIndices *indices = g_slice_new (CoglIndices);
 
75
 
 
76
  indices->buffer = cogl_object_ref (buffer);
 
77
  indices->offset = offset;
 
78
 
 
79
  indices->type = type;
 
80
 
 
81
  indices->immutable_ref = 0;
 
82
 
 
83
  return _cogl_indices_object_new (indices);
 
84
}
 
85
 
 
86
CoglIndices *
 
87
cogl_indices_new (CoglContext *context,
 
88
                  CoglIndicesType type,
 
89
                  const void *indices_data,
 
90
                  int n_indices)
 
91
{
 
92
  size_t buffer_bytes = sizeof_indices_type (type) * n_indices;
 
93
  CoglIndexBuffer *index_buffer = cogl_index_buffer_new (context, buffer_bytes);
 
94
  CoglBuffer *buffer = COGL_BUFFER (index_buffer);
 
95
  CoglIndices *indices;
 
96
  CoglError *ignore_error = NULL;
 
97
 
 
98
  _cogl_buffer_set_data (buffer,
 
99
                         0,
 
100
                         indices_data,
 
101
                         buffer_bytes,
 
102
                         &ignore_error);
 
103
  if (ignore_error)
 
104
    {
 
105
      cogl_error_free (ignore_error);
 
106
      cogl_object_unref (index_buffer);
 
107
      return NULL;
 
108
    }
 
109
 
 
110
  indices = cogl_indices_new_for_buffer (type, index_buffer, 0);
 
111
  cogl_object_unref (index_buffer);
 
112
 
 
113
  return indices;
 
114
}
 
115
 
 
116
CoglIndexBuffer *
 
117
cogl_indices_get_buffer (CoglIndices *indices)
 
118
{
 
119
  return indices->buffer;
 
120
}
 
121
 
 
122
CoglIndicesType
 
123
cogl_indices_get_type (CoglIndices *indices)
 
124
{
 
125
  _COGL_RETURN_VAL_IF_FAIL (cogl_is_indices (indices),
 
126
                            COGL_INDICES_TYPE_UNSIGNED_BYTE);
 
127
  return indices->type;
 
128
}
 
129
 
 
130
size_t
 
131
cogl_indices_get_offset (CoglIndices *indices)
 
132
{
 
133
  _COGL_RETURN_VAL_IF_FAIL (cogl_is_indices (indices), 0);
 
134
 
 
135
  return indices->offset;
 
136
}
 
137
 
 
138
static void
 
139
warn_about_midscene_changes (void)
 
140
{
 
141
  static CoglBool seen = FALSE;
 
142
  if (!seen)
 
143
    {
 
144
      g_warning ("Mid-scene modification of indices has "
 
145
                 "undefined results\n");
 
146
      seen = TRUE;
 
147
    }
 
148
}
 
149
 
 
150
void
 
151
cogl_indices_set_offset (CoglIndices *indices,
 
152
                         size_t offset)
 
153
{
 
154
  _COGL_RETURN_IF_FAIL (cogl_is_indices (indices));
 
155
 
 
156
  if (G_UNLIKELY (indices->immutable_ref))
 
157
    warn_about_midscene_changes ();
 
158
 
 
159
  indices->offset = offset;
 
160
}
 
161
 
 
162
static void
 
163
_cogl_indices_free (CoglIndices *indices)
 
164
{
 
165
  cogl_object_unref (indices->buffer);
 
166
  g_slice_free (CoglIndices, indices);
 
167
}
 
168
 
 
169
CoglIndices *
 
170
_cogl_indices_immutable_ref (CoglIndices *indices)
 
171
{
 
172
  _COGL_RETURN_VAL_IF_FAIL (cogl_is_indices (indices), NULL);
 
173
 
 
174
  indices->immutable_ref++;
 
175
  _cogl_buffer_immutable_ref (COGL_BUFFER (indices->buffer));
 
176
  return indices;
 
177
}
 
178
 
 
179
void
 
180
_cogl_indices_immutable_unref (CoglIndices *indices)
 
181
{
 
182
  _COGL_RETURN_IF_FAIL (cogl_is_indices (indices));
 
183
  _COGL_RETURN_IF_FAIL (indices->immutable_ref > 0);
 
184
 
 
185
  indices->immutable_ref--;
 
186
  _cogl_buffer_immutable_unref (COGL_BUFFER (indices->buffer));
 
187
}
 
188
 
 
189
CoglIndices *
 
190
cogl_get_rectangle_indices (CoglContext *ctx, int n_rectangles)
 
191
{
 
192
  int n_indices = n_rectangles * 6;
 
193
 
 
194
  /* Check if the largest index required will fit in a byte array... */
 
195
  if (n_indices <= 256 / 4 * 6)
 
196
    {
 
197
      /* Generate the byte array if we haven't already */
 
198
      if (ctx->rectangle_byte_indices == NULL)
 
199
        {
 
200
          uint8_t *byte_array = g_malloc (256 / 4 * 6 * sizeof (uint8_t));
 
201
          uint8_t *p = byte_array;
 
202
          int i, vert_num = 0;
 
203
 
 
204
          for (i = 0; i < 256 / 4; i++)
 
205
            {
 
206
              *(p++) = vert_num + 0;
 
207
              *(p++) = vert_num + 1;
 
208
              *(p++) = vert_num + 2;
 
209
              *(p++) = vert_num + 0;
 
210
              *(p++) = vert_num + 2;
 
211
              *(p++) = vert_num + 3;
 
212
              vert_num += 4;
 
213
            }
 
214
 
 
215
          ctx->rectangle_byte_indices
 
216
            = cogl_indices_new (ctx,
 
217
                                COGL_INDICES_TYPE_UNSIGNED_BYTE,
 
218
                                byte_array,
 
219
                                256 / 4 * 6);
 
220
 
 
221
          g_free (byte_array);
 
222
        }
 
223
 
 
224
      return ctx->rectangle_byte_indices;
 
225
    }
 
226
  else
 
227
    {
 
228
      if (ctx->rectangle_short_indices_len < n_indices)
 
229
        {
 
230
          uint16_t *short_array;
 
231
          uint16_t *p;
 
232
          int i, vert_num = 0;
 
233
 
 
234
          if (ctx->rectangle_short_indices != NULL)
 
235
            cogl_object_unref (ctx->rectangle_short_indices);
 
236
          /* Pick a power of two >= MAX (512, n_indices) */
 
237
          if (ctx->rectangle_short_indices_len == 0)
 
238
            ctx->rectangle_short_indices_len = 512;
 
239
          while (ctx->rectangle_short_indices_len < n_indices)
 
240
            ctx->rectangle_short_indices_len *= 2;
 
241
 
 
242
          /* Over-allocate to generate a whole number of quads */
 
243
          p = short_array = g_malloc ((ctx->rectangle_short_indices_len
 
244
                                       + 5) / 6 * 6
 
245
                                      * sizeof (uint16_t));
 
246
 
 
247
          /* Fill in the complete quads */
 
248
          for (i = 0; i < ctx->rectangle_short_indices_len; i += 6)
 
249
            {
 
250
              *(p++) = vert_num + 0;
 
251
              *(p++) = vert_num + 1;
 
252
              *(p++) = vert_num + 2;
 
253
              *(p++) = vert_num + 0;
 
254
              *(p++) = vert_num + 2;
 
255
              *(p++) = vert_num + 3;
 
256
              vert_num += 4;
 
257
            }
 
258
 
 
259
          ctx->rectangle_short_indices
 
260
            = cogl_indices_new (ctx,
 
261
                                COGL_INDICES_TYPE_UNSIGNED_SHORT,
 
262
                                short_array,
 
263
                                ctx->rectangle_short_indices_len);
 
264
 
 
265
          g_free (short_array);
 
266
        }
 
267
 
 
268
      return ctx->rectangle_short_indices;
 
269
    }
 
270
}
 
271