50 }
else if (bits < 53) {
58 mpfr_set_prec(o->
centerx, mpfr_get_prec(cx));
59 mpfr_set_prec(o->
centery, mpfr_get_prec(cy));
60 mpfr_set_prec(o->
radius, mpfr_get_prec(r));
61 mpfr_set(o->
centerx, cx, MPFR_RNDN);
62 mpfr_set(o->
centery, cy, MPFR_RNDN);
63 mpfr_set(o->
radius, r, MPFR_RNDN);
92 memset(s, 0,
sizeof(
struct render));
109 glClampColor(GL_CLAMP_VERTEX_COLOR, GL_FALSE);glGetError();
D;
110 glClampColor(GL_CLAMP_READ_COLOR, GL_FALSE);
D;
111 glClampColor(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE);glGetError();
D;
113 glActiveTexture(GL_TEXTURE0 +
TEX_RGB);
114 glBindTexture(GL_TEXTURE_2D, s->
rgb_tex);
D;
115 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
D;
116 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
D;
117 glGenTextures(1, &s->
tex);
D;
118 glActiveTexture(GL_TEXTURE0 +
TEX_RAW);
119 glBindTexture(GL_TEXTURE_2D, s->
tex);
D;
120 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
D;
121 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
D;
122 glGenTextures(1, &s->
tex2);
D;
123 glActiveTexture(GL_TEXTURE0 +
TEX_FILLC);
124 glBindTexture(GL_TEXTURE_2D, s->
tex2);
D;
125 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
D;
126 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
D;
127 glGenFramebuffers(1, &s->
fbo);
D;
128 glGenQueries(1, &s->
query);
D;
129 glGenBuffers(2, s->
vbo);
D;
165 glDeleteTextures(1, &s->
tex);
D;
166 glDeleteTextures(1, &s->
tex2);
D;
167 glDeleteFramebuffers(1, &s->
fbo);
D;
168 glDeleteQueries(1, &s->
query);
D;
169 glDeleteBuffers(2, s->
vbo);
D;
196 bool render_reshape(
struct render *s,
int new_width,
int new_height,
int new_slice, GLsizei *bytes_allocated) {
199 #define CHECK assert(vbo_bytes > 0 && "--size is too big for my tiny GLsizei, try increasing --slice")
200 assert(
sizeof(
double) == 8 &&
"what kind of obscure system are you running on?");
201 GLsizei vbo_bytes = (new_width >> new_slice) * (new_height >> new_slice);
CHECK;
202 vbo_bytes *= (
DE ? 9 : 7);
CHECK;
203 vbo_bytes <<= 1;
CHECK;
204 vbo_bytes <<= 1;
CHECK;
205 vbo_bytes <<= 1;
CHECK;
206 for (
int i = 0; i < 2; ++i) {
207 glBindBuffer(GL_ARRAY_BUFFER, s->
vbo[i]);
D;
208 glBufferData(GL_ARRAY_BUFFER, vbo_bytes, 0, GL_DYNAMIC_COPY);
D;
209 glBindBuffer(GL_ARRAY_BUFFER, 0);
D;
211 GLsizei tex_bytes = 0;
212 glActiveTexture(GL_TEXTURE0 +
TEX_RGB);
D;
213 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, new_width, new_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
D;
214 tex_bytes += new_width * new_height * 4;
215 glActiveTexture(GL_TEXTURE0 +
TEX_RAW);
D;
216 glTexImage2D(GL_TEXTURE_2D, 0,
DE ? GL_RGB32F : GL_RG32F, new_width, new_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
D;
217 tex_bytes += new_width * new_height * 4 * (
DE ? 3 : 2);
219 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, new_width >> new_slice, new_height >> new_slice, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
D;
220 tex_bytes += (new_width >> new_slice) * (new_height >> new_slice) * 4 * 4;
221 if (bytes_allocated) {
222 *bytes_allocated = 2 * vbo_bytes + tex_bytes;
229 bool need_to_restart_rendering =
false;
239 return need_to_restart_rendering;
277 #define PINGPONG(fp,FP) \
278 void fp##_pingpong(struct render *s) { \
279 if (! (s->active_count == 0)) { \
280 fp##_step_do(&s->fp##_step, &s->active_count, s->vbo[1], s->query); \
281 GLuint unescaped = 0; \
282 fp##_unescaped_do(&s->fp##_unescaped, &unescaped, s->active_count, s->vbo[0], s->query); \
283 int escaped = s->active_count - unescaped; \
285 fp##_escaped_do(&s->fp##_escaped, s->active_count); \
287 if (completion_update(&s->completion, unescaped, escaped, 1, s->options.sharpness)) { \
288 if (completion_done(&s->completion)) { \
289 render_next_slice(s); \
292 s->slice_done = false; \
293 s->idle.f = fp##_pingpong; \
295 s->active_count = unescaped; \
297 render_next_slice(s); \
310 fp32_fillc_do(&s->
fp32_fillc, s->
vbo[1], s->
fbo, s->
tex, s->
tex2, s->
options.
width, s->
options.
height, s->
pass, s->
options.
slice, slice_x, slice_y);
316 s->
idle.
f = fp32_pingpong;
324 fp32_fillc_do(&s->
fp32_fillc, s->
vbo[1], s->
fbo, s->
tex, s->
tex2, s->
options.
width, s->
options.
height, s->
pass, s->
options.
slice, slice_x, slice_y);
330 s->
idle.
f = fp64_pingpong;
334 struct render *s = userdata;
357 mpfr_inits2(53, x, y, r, (mpfr_ptr) 0);
362 mpfr_clears(x, y, r, (mpfr_ptr) 0);
368 mpfr_clears(x, y, r, (mpfr_ptr) 0);
373 if (! (mpfr_number_p(x) && mpfr_number_p(y))) {
380 mpfr_clears(x, y, r, (mpfr_ptr) 0);
382 fp32_fillc_do(&s->
fp32_fillc, s->
vbo[0], s->
fbo, s->
tex, s->
tex2, s->
options.
width, s->
options.
height, s->
pass, s->
options.
slice, slice_x, slice_y);
383 glBindFramebuffer(GL_FRAMEBUFFER, s->
fbo);
D;
384 fpxx_init_do(&s->
fpxx_init, &s->
active_count, s->
vbo, s->
query, s->
pass, s->
options.
width >> s->
options.
slice, s->
options.
height >> s->
options.
slice, s->
options.
centerx, s->
options.
centery, s->
options.
radius, s->
refs->
set->
x, s->
refs->
set->
y);
385 glBindFramebuffer(GL_FRAMEBUFFER, 0);
D;
405 mpfr_t zx, zy, dzx, dzy;
406 mpfr_inits2(53, zx, zy, dzx, dzy, (mpfr_ptr) 0);
407 fpxx_approx_do(&s->
fpxx_approx, &s->
active_count, s->
vbo, s->
query, zx, zy, dzx, dzy, s->
pass, s->
options.
radius, s->
refs->
set->
x, s->
refs->
set->
y, s->
options.
series_approx, s->
slice_n == 0, s,
fpxx_start_atom_abort);
409 mpfr_clears(zx, zy, dzx, dzy, (mpfr_ptr) 0);
413 mpfr_clears(zx, zy, dzx, dzy, (mpfr_ptr) 0);
414 fpxx_escaped_start(&s->
fpxx_escaped, s->
tex, s->
fbo, s->
vbo[1], s->
escaperadius2, s->
options.
width, s->
options.
height, s->
options.
centerx, s->
options.
centery, s->
options.
radius, s->
refs->
set->
x, s->
refs->
set->
y);
416 s->
idle.
f = fpxx_pingpong;
426 glBindFramebuffer(GL_FRAMEBUFFER, s->
fbo);
D;
456 double iterations, exterior, interior, glitch;
460 fp32_colour_do(&s->fp32_colour, o->win_width, o->win_height, o->width, o->height, s->timeout || s->all_done, s->pass > 0 || s->all_done, o->show_glitches, pow(0.5, o->weight), o->slice, s->slice_n); \
461 glBindFramebuffer(GL_FRAMEBUFFER, s->fbo);D; \
462 poll_swap_buffers(poll); \
480 if (s->
pass < 1000) {