00001 #include <X11/Xlib.h>
00002 #include <X11/Xutil.h>
00003 #include <iostream>
00004 #include <unistd.h>
00005 #include <limits.h>
00006
00007 #include "during.h"
00008
00009 #include <time.h>
00010
00011 using namespace std;
00012 using namespace sc_core;
00013
00014 int *slice_numbers;
00015 int *slice_processed;
00016
00017 pthread_mutex_t slice_processed_mutex = PTHREAD_MUTEX_INITIALIZER;
00018 pthread_mutex_t xmutex = PTHREAD_MUTEX_INITIALIZER;
00019
00020
00021 int auto_loop = 0;
00022 int auto_wait = 0;
00023 int number_of_slices = 20;
00024 int number_of_threads = 1;
00025
00026
00027 const int width = 640;
00028 const int height = 480;
00029 const int rect_height = 10;
00030
00031
00032 int max_iteration = 3000;
00033 long double x_min = -2;
00034 long double x_max = 1;
00035 long double y_min = -1.3;
00036 long double y_max = 1.3;
00037
00038
00039 struct rect {
00040 int slice_number;
00041 int y_start;
00042 };
00043
00044 struct rect rect_to_draw;
00045
00046 Display *display;
00047 Window window;
00048 int screen;
00049 int depth;
00050 GC gc;
00051 char *buffer;
00052 XImage *image;
00053 Colormap cmap;
00054 int color_table[256];
00055
00056 void init_x()
00057 {
00058 static XSizeHints size_hints;
00059 Visual *visual;
00060 Window rootwin;
00061 XGCValues values;
00062 unsigned long valuemask = 0;
00063 display = XOpenDisplay(NULL);
00064
00065 if (display == NULL) {
00066 fprintf(stderr, "Failed to open Display!");
00067 exit(1);
00068 }
00069
00070 screen = DefaultScreen(display);
00071 depth = DefaultDepth(display, screen);
00072 visual = DefaultVisual(display, screen);
00073 cmap = DefaultColormap(display, screen);
00074 rootwin = RootWindow(display, screen);
00075 window = XCreateSimpleWindow(display, rootwin, 10, 10, width, height, 5,
00076 BlackPixel(display, screen),
00077 BlackPixel(display, screen));
00078
00079 size_hints.flags = PSize | PMinSize | PMaxSize;
00080 size_hints.min_width = width;
00081 size_hints.max_width = width;
00082 size_hints.min_height = height;
00083 size_hints.max_height = height;
00084
00085 XSetWindowColormap(display, window, cmap);
00086
00087
00088
00089 gc = XCreateGC(display, window, valuemask, &values);
00090
00091 XSetStandardProperties(display, window, "Mandelbrot", "Mandelbrot",
00092 None, 0, 0, &size_hints);
00093
00094 XSelectInput(display, window, ButtonPressMask | KeyPressMask);
00095 XMapWindow(display, window);
00096
00097 buffer = 0;
00098
00099 image =
00100 XCreateImage(display, visual, depth, ZPixmap, 0, buffer, width,
00101 height, 8, 0);
00102 {
00103
00104 int imgsize = image->height * image->bytes_per_line;
00105 buffer = (char *)malloc(imgsize);
00106 int i;
00107 for (i = 0; i < imgsize; i++)
00108 buffer[i] = 0;
00109 }
00110 image->data = buffer;
00111
00112 XPutImage(display, window, gc, image, 0, 0, 0, 0, width, height);
00113 }
00114
00115 void Xdraw_rect(struct rect j)
00116 {
00117
00118 int slice_number = j.slice_number;
00119 int y_start = j.y_start;
00120 int x_start = (width * slice_number) / number_of_slices;
00121 int x_end = (width * (slice_number + 1)) / number_of_slices;
00122
00123 XPutImage(display, window, gc, image,
00124 x_start, y_start,
00125 x_start, y_start, x_end - x_start, rect_height);
00126
00127
00128
00129
00130
00131 XSync(display, 0);
00132 }
00133
00134 void draw_screen()
00135 {
00136 pthread_mutex_lock(&xmutex);
00137 XPutImage(display, window, gc, image, 0, 0, 0, 0, width, height);
00138
00139
00140
00141
00142
00143 XSync(display, 0);
00144 pthread_mutex_unlock(&xmutex);
00145 }
00146
00147 void clear_screen()
00148 {
00149 int x;
00150 int y;
00151 for (x = 0; x < width; x++) {
00152 for (y = 0; y < height; y++) {
00153 XPutPixel(image, x, y, 0x505050);
00154 }
00155 }
00156 draw_screen();
00157 }
00158
00159 void coordinate_to_long_double(int x, int y, long double *xf, long double *yf)
00160 {
00161 *xf = (long double)x;
00162 *yf = (long double)y;
00163 *xf = (*xf / width) * (x_max - x_min) + x_min;
00164 *yf = (*yf / height) * (y_max - y_min) + y_min;
00165 }
00166
00167 int iteration_color(int iteration)
00168 {
00169 iteration <<= 2;
00170 while (1) {
00171 if (iteration <= 0xFF) {
00172 return iteration;
00173 }
00174 iteration -= 0xFF;
00175 if (iteration <= 0xFF) {
00176 return (iteration << 8) + (0xFF - iteration);
00177 }
00178 iteration -= 0xFF;
00179 if (iteration <= 0xFF) {
00180 return (iteration << 16) + ((0xFF - iteration) << 8);
00181 }
00182 iteration -= 0xFF;
00183 if (iteration <= 0xFF) {
00184 return ((0xFF - iteration) << 16);
00185 }
00186 iteration -= 0xFF;
00187 }
00188 }
00189
00190 unsigned long mandelbrot_pixel(int x_int, int y_int)
00191 {
00192 long double x0, y0, x, y;
00193 int iteration = 0;
00194
00195 coordinate_to_long_double(x_int, y_int, &x0, &y0);
00196 x = x0;
00197 y = y0;
00198
00199 while (x * x + y * y <= 4.0 && iteration++ < max_iteration) {
00200 long double xtemp = x * x - y * y + x0;
00201 y = 2 * x * y + y0;
00202 x = xtemp;
00203 }
00204 if (iteration >= max_iteration) {
00205 return 0;
00206 } else {
00207
00208 return iteration_color(iteration);
00209 }
00210 }
00211
00212 void ask_draw_rect(struct rect j)
00213 {
00214 pthread_mutex_lock(&xmutex);
00215 Xdraw_rect(j);
00216 pthread_mutex_unlock(&xmutex);
00217 }
00218
00219 void draw_slice(int slice_number)
00220 {
00221 int x, y;
00222 for (y = 0; y < height; y++) {
00223 for (x = (width * slice_number) / number_of_slices;
00224 x < (width * (slice_number + 1)) / number_of_slices; x++) {
00225 XPutPixel(image, x, y, mandelbrot_pixel(x, y));
00226 }
00227 if (y % rect_height == rect_height - 1) {
00228 struct rect j;
00229 j.slice_number = slice_number;
00230 j.y_start = y - (y % rect_height);
00231 ask_draw_rect(j);
00232 }
00233 }
00234 }
00235
00236 void init()
00237 {
00238 int i;
00239 slice_numbers = new int[number_of_slices];
00240 slice_processed = new int[number_of_slices];
00241 for (i = 0; i < number_of_slices; i++)
00242 slice_processed[i] = 0;
00243
00244 init_x();
00245 }
00246
00247
00248
00249
00250
00251
00252
00253 struct prodcons_sol : sc_core::sc_module, sc_during
00254 {
00255
00256 void drawer_process();
00257
00258 void draw_slice_thread_shop();
00259
00260 SC_CTOR(prodcons_sol) {
00261 SC_THREAD(drawer_process);
00262 }
00263 };
00264
00265 void prodcons_sol::drawer_process()
00266 {
00267 during(100.0, SC_NS, boost::bind(&prodcons_sol::draw_slice_thread_shop, this));
00268 }
00269
00270 void prodcons_sol::draw_slice_thread_shop()
00271 {
00272 int i;
00273 while (1) {
00274 pthread_mutex_lock(&slice_processed_mutex);
00275 for (i = 0; i < number_of_slices; i++)
00276 if (slice_processed[i] == 0)
00277 break;
00278 if (i == number_of_slices) {
00279 pthread_mutex_unlock(&slice_processed_mutex);
00280 return;
00281 }
00282 printf("Processing slice %d\n", i);
00283 slice_processed[i] = 1;
00284 pthread_mutex_unlock(&slice_processed_mutex);
00285 draw_slice(i);
00286 }
00287 }
00288
00289 int sc_main(int argc, char *argv[])
00290 {
00291
00292 int i;
00293
00294 for (i = 1; i < argc; i++) {
00295 if (!strcmp(argv[i], "--wait"))
00296 auto_wait = 1;
00297 else if (!strcmp(argv[i], "--nb-slices")) {
00298 i++;
00299 number_of_slices = atoi(argv[i]);
00300 } else {
00301 printf("ERROR: Unknown option %s\n", argv[i]);
00302 exit(1);
00303 }
00304 }
00305
00306 vector<prodcons_sol *> vect(number_of_slices);
00307 char s[500];
00308 for(unsigned int i = 0; i < vect.size(); i++) {
00309 sprintf(s, "module_%d", i);
00310 vect[i] = new prodcons_sol(s);
00311 }
00312
00313 init();
00314 clear_screen();
00315
00316 {
00317 measure_time t;
00318 sc_start();
00319 }
00320
00321 if (auto_wait)
00322 sleep(1);
00323
00324 return 0;
00325 }