ray 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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);