Threadsafe offscreen drawing?

Here’s the idea
I want to draw to a huge offscreen buffer usig thread().
Then I want to display the progress in the main window, in a scaled down size.
Does not work, it displays the scaled down image, but only once the thread has finished… :frowning:
what am I missing?

PGraphics pg;
boolean done;

void setup() {
  size(640, 360);
  thread("drawOffscreen");
}

void draw() {
  image(pg,160,80,320,200);
  if (done) {
   exit();
  }
}

void drawOffscreen() {
  done = false;
  pg = createGraphics(3200, 2000);
  pg.beginDraw();
  pg.background(102);
  for (int i=0; i <= 10000 ; i++) {
      pg.stroke(round(random(255)));
    pg.line(random(pg.width), random(pg.height), random(pg.width), random(pg.height));
  }
  pg.endDraw();
  pg.save("test.png");
  done = true;
}
1 Like

Anyway it should be volatile boolean done;
So all threads can see how other threads have altered done, otherwise done could be effectively thread local to each thread, as though they each had their own independent version of done. Also you have multiple problems in the code like potentially creating pg after draw has been called a number of times. pg should be created in setup. It may be not possible to do what you want so easily because there are multiple issues to figure out.
This is as far as I got, but still it does not work.

volatile PGraphics pg;
volatile boolean done;

void setup() {
  size(640, 360);
  pg = createGraphics(3200, 2000);
  pg.beginDraw();
  thread("drawOffscreen");
}

void draw() {
  image(pg, 160, 80, 320, 200);
  if (done) {
    exit();
  }
}

void drawOffscreen() {
  pg.background(102);
  for (int i=0; i <= 10000; i++) {
    pg.stroke(round(random(255)));
    pg.line(random(pg.width), random(pg.height), random(pg.width), random(pg.height));
  }
  pg.endDraw();
  pg.save("test.png");
  done = true;
}

1 Like

It would be a lot less painful simply to draw the image incrementally in the draw function using a counter to keep track of where you are. Perhaps setting the frameRate () overly high.

The renderers aren’t thread safe themselves, although you might just get away with this with the default renderer.

You can’t draw the result in one thread while another is inside beginDraw / endDraw. You might be able to do multiple thread / done calls for different sections of the image and only draw the result between.

The non-threaded incremental approach is the right one!

2 Likes