/* * render.c * * Created on: 15.01.2018 * Author: Superleo1810 */ #include "render.h" #define HAVE_STRUCT_TIMESPEC #include void render_init(Config *config, u32 (*sfunc) (double, double, u32)) { _config = config; _sfunc = sfunc; ui_render.window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); gtk_window_set_default_size(ui_render.window, config->width, config->height); ui_render.frame = GTK_FRAME(gtk_frame_new(NULL)); gtk_container_add(GTK_CONTAINER(ui_render.window), ui_render.frame); ui_render.drawing_area = GTK_DRAWING_AREA(gtk_drawing_area_new()); gtk_widget_set_size_request(GTK_WIDGET(ui_render.drawing_area), config->width, config->height); g_signal_connect(G_OBJECT(ui_render.drawing_area), "draw", G_CALLBACK(on_draw), NULL); gtk_container_add(GTK_CONTAINER(ui_render.frame), ui_render.drawing_area); } void render_show() { gtk_widget_show_all(GTK_WIDGET(ui_render.window)); } void on_draw(GtkWidget *widget, cairo_t *cr, gpointer data) { cairo_surface_t *image; // TODO: MUSS UNBEDINGT SEPARAT GECALLT WERDEN, SONST KEINE 60 FPS image = render_surface(); cairo_set_source_surface(cr, image, 0, 0); cairo_paint(cr); } struct arg_thread { cairo_surface_t *result; unsigned short threadCount; unsigned short threadNumber; unsigned char *current_row; }; void *imageCalcThread(void *arguments) { struct arg_thread *args = arguments; cairo_surface_t *result = args->result; unsigned int threadCount = args->threadCount; unsigned int threadNumber = args->threadNumber; unsigned char *current_row = args->current_row; int stride; double x_math, y_math; u32 iterations; printf("thread calculating %s",result); current_row = cairo_image_surface_get_data(result); stride = cairo_image_surface_get_stride(result); //Calculating start and endpoint for current thread to calculate int startingPoint = (_config->height/threadCount)*(threadNumber); int endPoint = ((_config->height/threadCount)*(threadNumber + 1)) - 1; for (int y = startingPoint; y < endPoint && y < _config->height; y++) { u32 *row = (void *) current_row; for (int x = 0; x < _config->width; x++) { x_math = /*x_MIN*/-2.0 + ((double) x * (/*x_MAX*/1.0 - /*x_MIN*/-2.0)) / _config->width; y_math = /*y_MIN*/-1.0 + ((double) (_config->height - y) * (/*y_MAX*/1.0 - /*y_MIN*/-1.0)) / _config->height; iterations = _sfunc(x_math, y_math, _config->iterations); row[x] = (((1<<24)-1)*iterations)/_config->iterations; // if (iterations > 1<<8) // printf("schon gruen\n"); } current_row += stride; } } cairo_surface_t *render_surface() { cairo_surface_t *result; unsigned short threadCount = 4; unsigned char *current_row; result = cairo_image_surface_create(CAIRO_FORMAT_RGB24, _config->width, _config->height); if (cairo_surface_status(result) != CAIRO_STATUS_SUCCESS) return result; cairo_surface_flush(result); //initialize thread related values and put them into a struct, as just one parameter is passed struct arg_thread args; args.result = result; args.threadCount = threadCount; args.current_row = current_row; pthread_t tid; //Create threads up to the number specified in threadCount for (int i = 0; i < threadCount; i++){ args.threadNumber = i; pthread_create(&tid, NULL, imageCalcThread, (void *)&args); } //Wait for threads to finish and continue with the program pthread_join(tid,NULL); cairo_surface_mark_dirty(result); return result; }