# Renderer faster than JavaFX 2D

**URL:** <https://discourse.processing.org/t/renderer-faster-than-javafx-2d/42648>\
**Category:** Coding Questions\
**Created:** [August 24, 2023, 3:57am UTC](https://discourse.processing.org/t/renderer-faster-than-javafx-2d/42648 "2023-08-24T03:57:22Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![MrImskiy](https://avatars.discourse-cdn.com/v4/letter/m/5f8ce5/32.png) [@MrImskiy](https://discourse.processing.org/u/MrImskiy)\
**Post date:** [August 24, 2023, 3:57am UTC](https://discourse.processing.org/t/renderer-faster-than-javafx-2d/42648/1 "2023-08-24T03:57:22Z")

</div>

Hi everyone!

Is there any renderer that is faster than JavaFX 2D?

Thanks in advance,

MrImskiy

---

<div class="post-metadata">

**Author:** ![josephh](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/josephh/32/210_2.png) [@josephh](https://discourse.processing.org/u/josephh)\
**Post date:** [August 24, 2023, 8:46am UTC](https://discourse.processing.org/t/renderer-faster-than-javafx-2d/42648/2 "2023-08-24T08:46:07Z")

</div>

Hi @MrImskiy,

> [@MrImskiy](#):
>
> faster than JavaFX 2D

Faster for which type of workload? What do you want to display and how?

---

<div class="post-metadata">

**Author:** ![MrImskiy](https://avatars.discourse-cdn.com/v4/letter/m/5f8ce5/32.png) [@MrImskiy](https://discourse.processing.org/u/MrImskiy)\
**Post date:** [August 24, 2023, 10:48am UTC](https://discourse.processing.org/t/renderer-faster-than-javafx-2d/42648/3 "2023-08-24T10:48:33Z")

</div>

Thanks for replying @josephh!

I have a GUI with two oscilloscopes. The first oscilloscope displays the original signal, and the second oscilloscope displays the manipulated signal. The manipulations that are made are various: high-pass filter, low-pass filter, integration, etc.

The signals are coming from the MPU6050 sensor, which consists of a gyroscope and an accelerometer. The goal is to filter those two sensors appropriately, and to integrate the gyroscope once, to get an angle, and the accelerometer twice, to get displacement. All this (plotting included) is happening realtime.

For this application, I need an iteration time that is really small, especially for the double integration of the accelerometer, because otherwise, the signal manipulations will give a very erroneous result. When I integrate the acceleration once, I can, kind of, recognize a velocity, but when I integrate a second time, the displacement is nowhere to be recognized.

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [August 24, 2023, 11:14am UTC](https://discourse.processing.org/t/renderer-faster-than-javafx-2d/42648/4 "2023-08-24T11:14:10Z")

</div>

> [@MrImskiy](#):
>
> All this (plotting included) is happening realtime.

You do not have to process data during each frame.

This example generates data in a separate thread and updates the sketch window at the selected frameRate and is frameRate independent:

```auto
// Generate data in a thread
// GLV
// 2023-8-24

IntList data;
int counter;

void setup() 
  {
  size(800, 300);
  data = new IntList();
  tNow = millis();
  thread("requestData"); // Generates new data every 2 ms
  frameRate(60); //default
  }

void draw() 
  {
  background(0);
  
  synchronized (data) 
    {
    for(int i=0; i<data.size(); i++)
      {
      stroke(255, 255, 64);
      strokeWeight(3);
      point(i, data.get(i));
      }
    }
  }

// This is a separate thread

int tLast = 0;
int tNow;

void requestData() 
  {
  while(true)
    {
    tNow = millis();  
    if(tNow >= tLast+2) // +1 is minimum or will crash
      {
      println(frameCount, tNow-tLast); // Development
      
      int x = counter;
      float th = x*(TAU/360);
      int y = (int)(150+80*sin(th)*cos(th*10)); // Amplitude modulation
      
      // buffer
      synchronized (data) 
        {
        data.append(y);  
        if(data.size() > width) 
          {
          data.remove(0);   
          }
        }
      counter++;
   
      tLast = tNow;
      }
    }
  }    
  
void mousePressed()
  {
  data.clear(); // clears buffer  
  }

```

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/5/8/581e64db547f4eb0d0aea783cfa374cc82814873.png)

The above example was something I cooked up a few days ago to simulate data in place of external events (incoming serial data in this case).

`:)`

---

<div class="post-metadata">

**Author:** ![MrImskiy](https://avatars.discourse-cdn.com/v4/letter/m/5f8ce5/32.png) [@MrImskiy](https://discourse.processing.org/u/MrImskiy)\
**Post date:** [August 24, 2023, 11:27am UTC](https://discourse.processing.org/t/renderer-faster-than-javafx-2d/42648/5 "2023-08-24T11:27:49Z")

</div>

Thanks for the reply @glv ! Is `requestData()` continuously called in `setup()` ? What is the function of `synchronized()` ?

---

<div class="post-metadata">

**Author:** ![micycle](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/micycle/32/201_2.png) [@micycle](https://discourse.processing.org/u/micycle)\
**Post date:** [August 24, 2023, 12:38pm UTC](https://discourse.processing.org/t/renderer-faster-than-javafx-2d/42648/6 "2023-08-24T12:38:42Z")

</div>

I find the FX2D renderer to be the fastest of the Processing renderers for 2D geometry primitives.

---

<div class="post-metadata">

**Author:** ![MrImskiy](https://avatars.discourse-cdn.com/v4/letter/m/5f8ce5/32.png) [@MrImskiy](https://discourse.processing.org/u/MrImskiy)\
**Post date:** [August 24, 2023, 12:40pm UTC](https://discourse.processing.org/t/renderer-faster-than-javafx-2d/42648/7 "2023-08-24T12:40:02Z")

</div>

Another question: Why do the points start drawing at the utmost right of the window when the code explicitly says that it should start at x = 0?:

```auto
void draw(){
  background(0);
  synchronized (data){
    for(int i=0; i<data.size(); i++){
      stroke(255, 255, 64);
      strokeWeight(1);
      point(i, data.get(i));
    }
  }
}

```

---

<div class="post-metadata">

**Author:** ![MrImskiy](https://avatars.discourse-cdn.com/v4/letter/m/5f8ce5/32.png) [@MrImskiy](https://discourse.processing.org/u/MrImskiy)\
**Post date:** [August 24, 2023, 12:41pm UTC](https://discourse.processing.org/t/renderer-faster-than-javafx-2d/42648/8 "2023-08-24T12:41:46Z")

</div>

Thanks for the reply @micycle ! Some applications need a faster performance unfortunately…

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [August 24, 2023, 5:03pm UTC](https://discourse.processing.org/t/renderer-faster-than-javafx-2d/42648/9 "2023-08-24T17:03:34Z")

</div>

> [@MrImskiy](#):
>
> Is `requestData()` continuously called in `setup()` ?

No it is creating a _thread_ to simulate asynchronous data. This thread runs as a separate _process_ and is independent of the rest of the sketch code. The created thread simply adds new data to the end of the list (`data`) and removes data from the front of the list to make sure the list length does not exceed a maximum level.

> [@MrImskiy](#):
>
> What is the function of `synchronized()` ?

The main thread has the draw method and will display the data in the list. Since we have two threads sharing the list `data` then we must prevent both threads accessing the list at the same time as it would create a concurrent access exception and the sketch would crash. The code

```auto
synchronized (data) {
  // synchronized code block
}

```

means do not execute the code in the block if another thread is currently accessing the object `data`

> [@MrImskiy](#):
>
> Why do the points start drawing at the utmost right of the window when the code explicitly says that it should start at x = 0?:

They started on the left for me and the graph moves to the left because the points at the front are being removed.

FYI the code does not implement a _circular buffer_ because elements are being added and removed from the list. A true circular buffer has a fixed number of elements and they are reused / overwritten as needed so would be faster.

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [August 24, 2023, 5:57pm UTC](https://discourse.processing.org/t/renderer-faster-than-javafx-2d/42648/10 "2023-08-24T17:57:55Z")

</div>

I have adapted @glv’s code to make use of a circular buffer / array. Here it is

```auto
// Generate data in a thread
// GLV
// and adapted to use a circular buffer / array by Quark
// 2023-8-24

// Code does NOT include synchronization as yet.

int[] data;
int front = -1, back = 0;
int counter;

void setup() {
  size(800, 300);
  data = new int[width];
  tNow = millis();
  thread("requestData"); // Generates new data every 2 ms
  frameRate(60); //default
}

void draw() {
  background(0);

  synchronized (data) {
    stroke(255, 255, 64);
    strokeWeight(1.5);
    int idx = front, last = (back-1 + data.length) % data.length;
    int x = 0;
    while (idx >= 0 && idx != last) {
      point(x++, data[idx++]);
      idx %= data.length;
    }
  }
}

// This is a separate thread
int tLast = 0;
int tNow;

void requestData() {
  while (true) {
    tNow = millis();
    if (tNow >= tLast+2) { // +1 is minimum or will crash
      println(frameCount, tNow-tLast); // Development
      int x = counter;
      float th = x*(TAU/360);
      int y = (int)(150+80*sin(th)*cos(th*10)); // Amplitude modulation
      // add data to circular buffer
      synchronized (data) {
        if (front == back) { // handle fully filled list
          data[front] = y;
          back = (back + 1) % data.length;
          front = back;
        } else if (front != -1) { // handle part filled list
          data[back] = y;
          back = (back + 1) % data.length;
        } else { // handle empty list
          front = 0;
          back = 1;
          data[front] = y;
        }
      }
      counter++;
      tLast = tNow;
    }
  }
}

```

---

<div class="post-metadata">

**Author:** ![MrImskiy](https://avatars.discourse-cdn.com/v4/letter/m/5f8ce5/32.png) [@MrImskiy](https://discourse.processing.org/u/MrImskiy)\
**Post date:** [August 24, 2023, 6:05pm UTC](https://discourse.processing.org/t/renderer-faster-than-javafx-2d/42648/11 "2023-08-24T18:05:29Z")

</div>

Thank you very much @quark for the explanation and the code! Much appreciated! 😃

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [August 25, 2023, 11:36am UTC](https://discourse.processing.org/t/renderer-faster-than-javafx-2d/42648/12 "2023-08-25T11:36:57Z")

</div>

> [@MrImskiy](#):
>
> The signals are coming from the MPU6050 sensor,

I’ll be working with these soon (soldering up today!) and took an interest.

How is your project collecting the data from the sensor and sharing with Processing?  
I do not need or want to see code… just a simple description of the system.

Very busy these days for me… pleased to see your questions were answered.

`:)`

---

<div class="post-metadata">

**Author:** ![MrImskiy](https://avatars.discourse-cdn.com/v4/letter/m/5f8ce5/32.png) [@MrImskiy](https://discourse.processing.org/u/MrImskiy)\
**Post date:** [August 25, 2023, 1:23pm UTC](https://discourse.processing.org/t/renderer-faster-than-javafx-2d/42648/13 "2023-08-25T13:23:33Z")

</div>

Nice to know that you took an interest! 😃

And yes, your code seems to solve my problem 🙂

Concerning the sensor:

The MPU6050 is wired to the ESP32 microcontroller board, and the data is sent via bluetooth to my pc. In processing, I just have to select the right COM port to receive the data. ESP32 has built-in bluetooth and WiFi.

---

<div class="post-metadata">

**Author:** ![scudly](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/scudly/32/5597_2.png) [@scudly](https://discourse.processing.org/u/scudly)\
**Post date:** [August 25, 2023, 2:09pm UTC](https://discourse.processing.org/t/renderer-faster-than-javafx-2d/42648/14 "2023-08-25T14:09:26Z")

</div>

I wonder how much buffering there is in the bluetooth hardware and drivers either on the ESP32 or on your PC or in Processing (Java). There might well not be any or at least be negligible, but if there is, it could create stair-stepping in your timing as several readings come in at once.

---

<div class="post-metadata">

**Author:** ![MrImskiy](https://avatars.discourse-cdn.com/v4/letter/m/5f8ce5/32.png) [@MrImskiy](https://discourse.processing.org/u/MrImskiy)\
**Post date:** [August 25, 2023, 4:49pm UTC](https://discourse.processing.org/t/renderer-faster-than-javafx-2d/42648/16 "2023-08-25T16:49:04Z")

</div>

It might be the case… How can I verify if there is any buffering?

---

<div class="post-metadata">

**Author:** ![scudly](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/scudly/32/5597_2.png) [@scudly](https://discourse.processing.org/u/scudly)\
**Post date:** [August 25, 2023, 7:26pm UTC](https://discourse.processing.org/t/renderer-faster-than-javafx-2d/42648/17 "2023-08-25T19:26:12Z")

</div>

No idea. I’ve never played with it.

Get your app working with a separate data collection thread first and see how well you can timestamp the data. If it’s smooth enough, then ignore what I said. If not, then see if you can find any driver settings in your OS that talk about buffering or window size to see if you can make them smaller.

You might also try testing with wifi or usb just to compare timings even if bluetooth is your ultimate choice.

---

<div class="post-metadata">

**Author:** ![MrImskiy](https://avatars.discourse-cdn.com/v4/letter/m/5f8ce5/32.png) [@MrImskiy](https://discourse.processing.org/u/MrImskiy)\
**Post date:** [August 26, 2023, 1:14pm UTC](https://discourse.processing.org/t/renderer-faster-than-javafx-2d/42648/18 "2023-08-26T13:14:28Z")

</div>

Why would you not put these calulations:

```auto
int x = counter;
float th = x*(TAU/360);
int y = (int)(150+80*sin(th)*cos(th*10)); // Amplitude modulation

```

inside `synchronized (data)` ?

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [August 26, 2023, 1:16pm UTC](https://discourse.processing.org/t/renderer-faster-than-javafx-2d/42648/19 "2023-08-26T13:16:22Z")

</div>

> [@MrImskiy](#):
>
> And yes, your code seems to solve my problem

The code I provided was a quick effort for me and should be treated as such.  
I head several versions on the go and trickled it down to something simple to share.

_Always scrutinize code that is shared on the Internet._

I am not confident that I put the _synchronized()_ in the correct or best place; it seemed right at the time and may revisit this another time.

You can often find references that help explain concepts on the Processing page (references, tutorials, examples, etc.) :

> **[thread() / Reference](https://processing.org/reference/thread_.html)**
>
> Processing sketches follow a specific sequence of steps: setup() first, followed by draw() over and over and over again in a loop. A thread is also a series of steps with a beginning, a …

There are Processing references and there are Java references. 🙂

Processing is built on top of Java and often has a wrapper method to call the underlying Java code. Sometimes the source code will help to clarify things.

The Processing [dist()](https://processing.org/reference/dist_.html) function can be found in the source code here:

[https://github.com/processing/processing4/blob/main/core/src/processing/core/PApplet.java#L4530](https://github.com/processing/processing4/blob/main/core/src/processing/core/PApplet.java#L4530) \< Give it a moment to open and go to the line!

I liked this _Introduction to Processing_ so sharing:  
[https://www.geeksforgeeks.org/introduction-to-processing-java/](https://www.geeksforgeeks.org/introduction-to-processing-java/)

I don’t have all the answers but do a lot of research, searching (some resources are better than others) and coding and eventually find my way.

And oh! I was typing this post and just after you came in with yours!  
Where we _synchronized()_?

`:)`

---

<div class="post-metadata">

**Author:** ![MrImskiy](https://avatars.discourse-cdn.com/v4/letter/m/5f8ce5/32.png) [@MrImskiy](https://discourse.processing.org/u/MrImskiy)\
**Post date:** [August 26, 2023, 1:17pm UTC](https://discourse.processing.org/t/renderer-faster-than-javafx-2d/42648/20 "2023-08-26T13:17:09Z")

</div>

Ok, I’ll see where I will get! thanks! 🙂

---

<div class="post-metadata">

**Author:** ![MrImskiy](https://avatars.discourse-cdn.com/v4/letter/m/5f8ce5/32.png) [@MrImskiy](https://discourse.processing.org/u/MrImskiy)\
**Post date:** [August 26, 2023, 1:41pm UTC](https://discourse.processing.org/t/renderer-faster-than-javafx-2d/42648/21 "2023-08-26T13:41:45Z")

</div>

😆 Nice one! 😝 Thanks for the info! 🙂

[Next page](https://discourse.processing.org/t/renderer-faster-than-javafx-2d/42648.md?page=2)
