ray 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/ext/mo.h CHANGED
@@ -14,6 +14,15 @@
14
14
  #include <assert.h>
15
15
  #include <string.h>
16
16
  #include <stdio.h>
17
+ #include <stddef.h>
18
+
19
+ #ifdef __cplusplus
20
+ extern "C" {
21
+ #endif
22
+
23
+ #if 0
24
+ }
25
+ #endif
17
26
 
18
27
  /**
19
28
  * Function pointer types
@@ -73,35 +82,61 @@ void mo_array_reserve(mo_array *ary, size_t size);
73
82
  void mo_array_shrink(mo_array *ary);
74
83
 
75
84
  /**
76
- * Doubly linked list.
85
+ * String.
77
86
  */
78
87
 
88
+ typedef mo_array mo_string;
89
+
90
+ void mo_string_init(mo_string *str);
91
+ void mo_string_init_from_cstr(mo_string *str, const char *cstr);
92
+ void mo_string_init_from_buf(mo_string *str, const char *cstr, size_t size);
93
+ void mo_string_replace(mo_string *str, const char *cstr);
94
+ size_t mo_string_len(mo_string *str);
95
+ void mo_string_append(mo_string *str, const char *cstr);
96
+ char *mo_string_cstr(mo_string *str);
97
+ int mo_string_cmp(mo_string *a, mo_string *b);
98
+
99
+ #define mo_string_at(str, i) mo_array_get_as(str, i, char)
100
+
101
+ typedef struct mo_list_it {
102
+ struct mo_list_it *prev, *next;
103
+ uint8_t data[];
104
+ } mo_list_it;
105
+
79
106
  typedef struct mo_list {
80
- struct mo_list *prev, *next;
107
+ mo_list_it *head;
108
+ mo_list_it *last;
81
109
 
82
110
  mo_release release;
83
111
  mo_copy copy;
84
112
 
85
113
  size_t el_size;
86
- uint8_t data[];
87
114
  } mo_list;
88
115
 
116
+ void mo_list_init(mo_list *list, size_t el_size);
117
+ void mo_list_release(mo_list *list);
118
+
89
119
  mo_list *mo_list_create(size_t el_size);
90
120
  void mo_list_free(mo_list *list);
91
121
 
92
- mo_list *mo_list_prepend(mo_list *list, void *data);
93
- mo_list *mo_list_insert(mo_list *list, void *data);
94
- mo_list *mo_list_delete(mo_list *list);
122
+ void mo_list_prepend(mo_list *list, mo_list_it *it, void *data);
123
+ void mo_list_insert(mo_list *list, mo_list_it *it, void *data);
124
+ void mo_list_delete(mo_list *list, mo_list_it *it);
95
125
 
96
- void mo_list_set(mo_list *list, void *data);
126
+ void mo_list_set(mo_list *list, mo_list_it *it, void *data);
97
127
 
98
- #define mo_list_data_ptr(list, type) ( (type*)list->data)
99
- #define mo_list_data_as(list, type) (*(type*)list->data)
128
+ #define mo_list_it_data_ptr(it, type) ( (type*)it->data)
129
+ #define mo_list_it_data_as(it, type) (*(type*)it->data)
100
130
 
101
131
  /**
102
132
  * Hash table.
103
133
  */
104
134
 
135
+ typedef struct mo_hash_list {
136
+ struct mo_hash_list *next;
137
+ uint8_t data[];
138
+ } mo_hash_list;
139
+
105
140
  typedef struct mo_hash {
106
141
  mo_array buffer;
107
142
 
@@ -121,9 +156,9 @@ typedef struct mo_hash {
121
156
  } mo_hash;
122
157
 
123
158
  typedef struct mo_hash_it {
124
- mo_hash *hash;
125
- mo_list *list;
126
- size_t id;
159
+ mo_hash *hash;
160
+ mo_hash_list *list;
161
+ size_t id;
127
162
  } mo_hash_it;
128
163
 
129
164
  int mo_hash_of_pointer(void *ptr);
@@ -135,6 +170,9 @@ int mo_hash_u32_cmp(const void *a, const void *b);
135
170
  int mo_hash_of_size(void *ptr);
136
171
  int mo_hash_size_cmp(const void *a, const void *b);
137
172
 
173
+ void mo_hash_init(mo_hash *hash, size_t key_size, size_t el_size);
174
+ void mo_hash_release(mo_hash *hash);
175
+
138
176
  mo_hash *mo_hash_create(size_t key_size, size_t el_size);
139
177
  void mo_hash_free(mo_hash *hash);
140
178
 
@@ -169,6 +207,9 @@ void mo_hash_it_next(mo_hash_it *it);
169
207
  typedef mo_hash mo_set;
170
208
  typedef mo_hash_it mo_set_it;
171
209
 
210
+ #define mo_set_init(set, key_size, el_size) mo_hash_init(set, key_size, el_size)
211
+ #define mo_set_release(set) mo_hash_init(set)
212
+
172
213
  #define mo_set_create(size) mo_hash_create(size, 0)
173
214
  #define mo_set_free(set) mo_hash_delete(set)
174
215
 
@@ -186,4 +227,8 @@ typedef mo_hash_it mo_set_it;
186
227
  #define mo_set_it_val_ptr(it, type) mo_hash_it_key_ptr(it, type)
187
228
  #define mo_set_it_val_as(it, type) mo_hash_it_key_as(it, type)
188
229
 
230
+ #ifdef __cplusplus
231
+ }
232
+ #endif
233
+
189
234
  #endif /* MY OWN HEADER'S GUARD! */
@@ -21,6 +21,7 @@ VALUE ray_polygon_alloc(VALUE self) {
21
21
 
22
22
  say_drawable_set_shader_proc(obj->drawable, ray_drawable_shader_proc);
23
23
  say_drawable_set_other_data(obj->drawable, (void*)rb);
24
+ rb_iv_set(rb, "@shader_attributes", Qnil);
24
25
 
25
26
  return rb;
26
27
  }
@@ -72,6 +73,7 @@ VALUE ray_polygon_line(int argc, VALUE *argv, VALUE self) {
72
73
 
73
74
  say_drawable_set_shader_proc(line->drawable, ray_drawable_shader_proc);
74
75
  say_drawable_set_other_data(line->drawable, (void*)rb);
76
+ rb_iv_set(rb, "@shader_attributes", Qnil);
75
77
 
76
78
  return rb;
77
79
  }
@@ -104,6 +106,7 @@ VALUE ray_polygon_rectangle(int argc, VALUE *argv, VALUE self) {
104
106
 
105
107
  say_drawable_set_shader_proc(poly->drawable, ray_drawable_shader_proc);
106
108
  say_drawable_set_other_data(poly->drawable, (void*)ret);
109
+ rb_iv_set(ret, "@shader_attributes", Qnil);
107
110
 
108
111
  return ret;
109
112
  }
@@ -141,6 +144,7 @@ VALUE ray_polygon_circle(int argc, VALUE *argv, VALUE self) {
141
144
 
142
145
  say_drawable_set_shader_proc(poly->drawable, ray_drawable_shader_proc);
143
146
  say_drawable_set_other_data(poly->drawable, (void*)ret);
147
+ rb_iv_set(ret, "@shader_attributes", Qnil);
144
148
 
145
149
  return ret;
146
150
  }
@@ -179,6 +183,7 @@ VALUE ray_polygon_ellipse(int argc, VALUE *argv, VALUE self) {
179
183
 
180
184
  say_drawable_set_shader_proc(poly->drawable, ray_drawable_shader_proc);
181
185
  say_drawable_set_other_data(poly->drawable, (void*)rb);
186
+ rb_iv_set(rb, "@shader_attributes", Qnil);
182
187
 
183
188
  return rb;
184
189
  }
@@ -5,24 +5,15 @@ static bool say_has_vao() {
5
5
  GLEW_VERSION_3_0;
6
6
  }
7
7
 
8
- static GLuint say_current_vbo = 0;
9
- static say_context *say_vbo_last_context = NULL;
10
-
11
8
  static void say_vbo_make_current(GLuint vbo) {
12
9
  say_context *context = say_context_current();
13
10
 
14
- if (context != say_vbo_last_context ||
15
- vbo != say_current_vbo) {
16
- say_current_vbo = vbo;
17
- say_vbo_last_context = context;
18
-
11
+ if (context->vbo != vbo) {
19
12
  glBindBuffer(GL_ARRAY_BUFFER, vbo);
13
+ context->vbo = vbo;
20
14
  }
21
15
  }
22
16
 
23
- static GLuint say_current_vao = 0;
24
- static say_context *say_vao_last_context = NULL;
25
-
26
17
  typedef struct {
27
18
  GLuint vao;
28
19
  say_context *context;
@@ -31,51 +22,51 @@ typedef struct {
31
22
  static void say_vao_make_current(GLuint vao) {
32
23
  say_context *context = say_context_current();
33
24
 
34
- if (context != say_vao_last_context ||
35
- vao != say_current_vao) {
36
- say_current_vao = vao;
37
- say_vao_last_context = context;
38
-
25
+ if (context->vao != vao) {
39
26
  glBindVertexArray(vao);
40
-
41
27
  say_index_buffer_rebind();
28
+
29
+ context->vao = vao;
42
30
  }
43
31
  }
44
32
 
45
- static say_buffer *say_current_buffer = NULL;
46
- static say_context *say_buffer_last_context = NULL;
47
-
48
33
  static void say_buffer_setup_pointer(say_buffer *buf);
49
34
 
50
35
  static void say_buffer_make_current(say_buffer *buf) {
51
36
  say_context *context = say_context_current();
52
37
 
53
- if (context != say_buffer_last_context ||
54
- buf != say_current_buffer) {
55
- say_current_buffer = buf;
56
- say_buffer_last_context = context;
57
-
38
+ if (context->buffer_obj != buf) {
58
39
  say_buffer_setup_pointer(buf);
40
+ context->buffer_obj = buf;
59
41
  }
60
42
  }
61
43
 
62
44
  static void say_vbo_will_delete(GLuint vbo) {
63
- if (vbo == say_current_vbo)
64
- say_current_vbo = 0;
45
+ mo_array *contexts = say_context_get_all();
46
+ for (size_t i = 0; i < contexts->size; i++) {
47
+ say_context *context = mo_array_get_as(contexts, i, say_context*);
48
+ if (context->vbo == vbo)
49
+ context->vbo = 0;
50
+ }
65
51
  }
66
52
 
67
53
  static void say_buffer_will_delete(say_buffer *buf) {
68
- if (buf == say_current_buffer)
69
- say_current_buffer = NULL;
54
+ mo_array *contexts = say_context_get_all();
55
+ for (size_t i = 0; i < contexts->size; i++) {
56
+ say_context *context = mo_array_get_as(contexts, i, say_context*);
57
+ if (context->buffer_obj == buf)
58
+ context->buffer_obj = NULL;
59
+ }
70
60
  }
71
61
 
72
62
  static void say_buffer_delete_vao_pair(say_vao_pair *pair) {
73
- /* TODO: finding out if the context is still alive, to avoid leaks */
74
- if (say_vao_last_context == pair->context && say_current_vao == pair->vao) {
75
- say_current_vao = 0;
76
- glDeleteVertexArrays(1, &pair->vao);
63
+ say_context *context = say_context_current();
77
64
 
65
+ if (context == pair->context && context->vao == pair->vao) {
66
+ glDeleteVertexArrays(1, &pair->vao);
78
67
  say_index_buffer_rebind();
68
+
69
+ context->vao = 0;
79
70
  }
80
71
  }
81
72
 
@@ -222,7 +213,6 @@ say_buffer *say_buffer_create(size_t vtype, GLenum type, size_t size) {
222
213
  buf->vaos->release = (say_destructor)say_buffer_delete_vao_pair;
223
214
  buf->vaos->hash_of = mo_hash_of_pointer;
224
215
  buf->vaos->key_cmp = mo_hash_pointer_cmp;
225
-
226
216
  }
227
217
  else
228
218
  buf->vaos = NULL;
@@ -13,29 +13,28 @@ typedef struct {
13
13
 
14
14
  typedef struct {
15
15
  say_buffer *buf;
16
- mo_list *ranges;
16
+ mo_list ranges;
17
17
  } say_global_buffer;
18
18
 
19
19
  static mo_array *say_global_buffers = NULL;
20
20
 
21
21
  static void say_global_buffer_free(say_global_buffer *buf) {
22
22
  say_buffer_free(buf->buf);
23
- if (buf->ranges) mo_list_free(buf->ranges);
23
+ mo_list_release(&buf->ranges);
24
24
  }
25
25
 
26
26
  static say_global_buffer *say_global_buffer_create(mo_array *bufs,
27
27
  size_t vtype, size_t size) {
28
28
  say_global_buffer buffer;
29
29
 
30
- buffer.buf = say_buffer_create(vtype, SAY_STREAM, size);
31
- buffer.ranges = NULL;
30
+ buffer.buf = say_buffer_create(vtype, SAY_STREAM, size);
31
+ mo_list_init(&buffer.ranges, sizeof(say_range));
32
32
 
33
33
  mo_array_push(bufs, &buffer);
34
34
 
35
35
  return mo_array_at(bufs, bufs->size - 1);
36
36
  }
37
37
 
38
-
39
38
  static void say_global_buffer_array_alloc(mo_array *ary) {
40
39
  mo_array_init(ary, sizeof(say_global_buffer));
41
40
  ary->release = (say_destructor)say_global_buffer_free;
@@ -47,15 +46,16 @@ static void say_global_buffer_array_free(mo_array *ary) {
47
46
 
48
47
  static size_t say_global_buffer_prepend(say_global_buffer *buf, size_t n) {
49
48
  say_range range = say_make_range(0, n);
50
- buf->ranges = mo_list_prepend(buf->ranges, &range);
49
+ mo_list_prepend(&buf->ranges, buf->ranges.head, &range);
51
50
  return 0;
52
51
  }
53
52
 
54
- static size_t say_global_buffer_insert(mo_list *list, size_t n) {
55
- say_range *previous = mo_list_data_ptr(list, say_range);
53
+ static size_t say_global_buffer_insert(mo_list *list, mo_list_it *it,
54
+ size_t n) {
55
+ say_range *previous = mo_list_it_data_ptr(it, say_range);
56
56
 
57
57
  say_range range = say_make_range(previous->loc + previous->size, n);
58
- mo_list_insert(list, &range);
58
+ mo_list_insert(list, it, &range);
59
59
 
60
60
  return range.loc;
61
61
  }
@@ -65,36 +65,34 @@ static size_t say_global_buffer_find(say_global_buffer *buf, size_t n) {
65
65
  if (n > say_buffer_get_size(buf->buf))
66
66
  return SAY_MAX_SIZE;
67
67
 
68
- if (!buf->ranges) {
69
- buf->ranges = mo_list_create(sizeof(say_range));
70
- say_range *range = mo_list_data_ptr(buf->ranges, say_range);
71
- *range = say_make_range(0, n);
68
+ if (!buf->ranges.head) {
69
+ return say_global_buffer_prepend(buf, n);
72
70
  }
73
71
 
74
- say_range *first = mo_list_data_ptr(buf->ranges, say_range);
72
+ say_range *first = mo_list_it_data_ptr(buf->ranges.head, say_range);
75
73
 
76
74
  /* There's room at the begin of the buffer */
77
75
  if (first->loc >= n)
78
- return say_global_buffer_prepend(buf, 0);
76
+ return say_global_buffer_prepend(buf, n);
79
77
 
80
- mo_list *it = buf->ranges;
78
+ mo_list_it *it = buf->ranges.head;
81
79
  for (; it->next; it = it->next) { /* stop before last element */
82
- say_range *current = mo_list_data_ptr(it, say_range);
83
- say_range *next = mo_list_data_ptr(it->next, say_range);
80
+ say_range *current = mo_list_it_data_ptr(it, say_range);
81
+ say_range *next = mo_list_it_data_ptr(it->next, say_range);
84
82
 
85
83
  size_t begin = current->loc + current->size;
86
84
  size_t end = next->loc;
87
85
 
88
86
  /* There's enough room between those two elements */
89
87
  if (end - begin >= n)
90
- return say_global_buffer_insert(it, n);
88
+ return say_global_buffer_insert(&buf->ranges, it, n);
91
89
  }
92
90
 
93
- say_range *last = mo_list_data_ptr(it, say_range);
91
+ say_range *last = mo_list_it_data_ptr(it, say_range);
94
92
 
95
93
  /* There's enough room at the end of the buffer */
96
94
  if ((last->loc + last->size + n) < say_buffer_get_size(buf->buf)) {
97
- return say_global_buffer_insert(it, n);
95
+ return say_global_buffer_insert(&buf->ranges, it, n);
98
96
  }
99
97
 
100
98
  /* Not enough room here */
@@ -106,14 +104,10 @@ static void say_global_buffer_delete_at(say_global_buffer *buf, size_t loc,
106
104
  if (!buf)
107
105
  return;
108
106
 
109
- for (mo_list *it = buf->ranges; it; it = it->next) {
110
- say_range *range = mo_list_data_ptr(it, say_range);
107
+ for (mo_list_it *it = buf->ranges.head; it; it = it->next) {
108
+ say_range *range = mo_list_it_data_ptr(it, say_range);
111
109
  if (range->loc == loc && range->size == range_size) {
112
- mo_list *next = it->next;
113
- mo_list_delete(it);
114
-
115
- if (it == buf->ranges) buf->ranges = next;
116
-
110
+ mo_list_delete(&buf->ranges, it);
117
111
  return;
118
112
  }
119
113
  }
@@ -121,8 +115,8 @@ static void say_global_buffer_delete_at(say_global_buffer *buf, size_t loc,
121
115
 
122
116
  static void say_global_buffer_reduce_size(say_global_buffer *buf, size_t loc,
123
117
  size_t old_size, size_t size) {
124
- for (mo_list *it = buf->ranges; it; it = it->next) {
125
- say_range *range = mo_list_data_ptr(it, say_range);
118
+ for (mo_list_it *it = buf->ranges.head; it; it = it->next) {
119
+ say_range *range = mo_list_it_data_ptr(it, say_range);
126
120
  if (range->loc == loc && range->size == size) {
127
121
  range->size = size;
128
122
  return;
@@ -22,6 +22,7 @@ static mo_array *say_all_ensured_contexts = NULL;
22
22
  static void say_context_create_initial();
23
23
  static void say_context_setup(say_context *context);
24
24
  static void say_context_setup_states(say_context *context);
25
+ static void say_context_setup_cache(say_context *context);
25
26
  static void say_context_glew_init();
26
27
 
27
28
  static uint32_t say_context_count = 0;
@@ -49,6 +50,15 @@ say_context *say_context_current() {
49
50
  return (say_context*)say_thread_variable_get(say_current_context);
50
51
  }
51
52
 
53
+ mo_array *say_context_get_all() {
54
+ if (!say_all_ensured_contexts) {
55
+ say_all_ensured_contexts = mo_array_create(sizeof(say_context*));
56
+ say_all_ensured_contexts->release = say_context_free_el;
57
+ }
58
+
59
+ return say_all_ensured_contexts;
60
+ }
61
+
52
62
  void say_context_ensure() {
53
63
  if (!say_ensured_context)
54
64
  say_ensured_context = say_thread_variable_create();
@@ -80,6 +90,7 @@ say_context *say_context_create() {
80
90
 
81
91
  say_context_setup(context);
82
92
  say_context_setup_states(context);
93
+ say_context_setup_cache(context);
83
94
 
84
95
  return context;
85
96
  }
@@ -95,6 +106,7 @@ say_context *say_context_create_for_window(say_window *window) {
95
106
  context->context = say_imp_context_create_for_window(shared,
96
107
  window->win);
97
108
  say_context_setup_states(context);
109
+ say_context_setup_cache(context);
98
110
 
99
111
  return context;
100
112
  }
@@ -156,6 +168,32 @@ static void say_context_setup_states(say_context *context) {
156
168
  glReadBuffer(GL_FRONT);
157
169
  }
158
170
 
171
+ static void say_context_setup_cache(say_context *context) {
172
+ context->texture_unit = 0;
173
+ for (size_t i = 0; i < 32; i++)
174
+ context->textures[i] = 0;
175
+
176
+ context->vao = 0;
177
+ context->vbo = 0;
178
+ context->buffer_obj = NULL;
179
+
180
+ context->program = 0;
181
+
182
+ context->ibo = 0;
183
+
184
+ context->pack_pbo = 0;
185
+ context->unpack_pbo = 0;
186
+
187
+ context->target = NULL;
188
+
189
+ context->blend_enabled = false;
190
+ context->src_blend_func = GL_SRC_ALPHA;
191
+ context->dst_blend_func = GL_ONE_MINUS_SRC_ALPHA;
192
+
193
+ context->fbo = 0;
194
+ context->rbo = 0;
195
+ }
196
+
159
197
  void say_context_clean_up() {
160
198
  if (say_all_ensured_contexts)
161
199
  mo_array_free(say_all_ensured_contexts);