# Why P2D is slower than default renderer？

**URL:** <https://discourse.processing.org/t/why-p2d-is-slower-than-default-renderer/23897>\
**Category:** Processing\
**Created:** [September 16, 2020, 8:24pm UTC](https://discourse.processing.org/t/why-p2d-is-slower-than-default-renderer/23897 "2020-09-16T20:24:41Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![IpNeNaEcRe](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/ipnenaecre/32/11223_2.png) [@IpNeNaEcRe](https://discourse.processing.org/u/IpNeNaEcRe)\
**Post date:** [September 16, 2020, 8:24pm UTC](https://discourse.processing.org/t/why-p2d-is-slower-than-default-renderer/23897/1 "2020-09-16T20:24:41Z")

</div>

Why P2D is much slower than default renderer? Here is the number of bubbles makes the FPS slower than 30.

- **Default renderer:** click 28 times(2800 bubbles)
- **P2D:** click 3 times(300 bubbles)
- **P3D:** click 55 times(5500 bubbles)

I don’t know why is this happened, did I use too much **random** functions in my code? Why P3D works well but P2D works so badly.

This is the code. SOMEBODY HELP!

```auto
Bubble[] bubbles = new Bubble[0];
int total = 0;

void setup() {
  size(800, 800, P2D);
  smooth();
}

void draw() {
  background(255);

  for (int i=0; i<bubbles.length; i++) { 
    bubbles[i].display();
    bubbles[i].ascend();
    bubbles[i].edge();
  }
   
  text("fps :"+frameRate, 20, 20);
}

void mouseClicked() {
  for (int i=0; i<100; i++) {
    Bubble b = new Bubble();
    bubbles = (Bubble[])append(bubbles, b);
  }
}

class Bubble {
  float x;
  float y;
  float r;
  float n;
  color c = color(random(255), random(255), random(255), random(255));
  float speed;

  Bubble() {
    x = random(width);
    y = height+r;
    r = random(2,6);
    speed = random(1, 4);
  }

  Bubble(float tempR) {
    x = random(width);
    y = height+r;
    r = tempR;
    speed = random(2, 6);
  }

  Bubble(float tempR, float tempS) {
    x = random(width);
    y = height+r;
    r = tempR;
    speed = tempS;
  }

  void display() {
    fill(c);
    stroke(100);
    strokeWeight(2);
    circle(x, y, 2*r);
  }

  void ascend() {
    x = x+random(-5, 5);
    y = y - speed;
  }

  void edge() {
    if (x<=r) {
      circle(x+width, y, 2*r);
    } else if (x>=width-r) {
      circle(x-width, y, 2*r);
    }

    if (y<=r&&y>=-r) {
      circle(x, y+height, 2*r);
      if (x<=r) {
        circle(x+width, y+height, 2*r);
      } else if (x>=width-r) {
        circle(x-width, y+height, 2*r);
      }
    } else if (y<=-r) {
      y = y+height;
    }
  }
}

```

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [September 16, 2020, 9:35pm UTC](https://discourse.processing.org/t/why-p2d-is-slower-than-default-renderer/23897/2 "2020-09-16T21:35:49Z")

</div>

> [@IpNeNaEcRe](#):
>
> Why P2D is much slower than default renderer?

I simply dunno why the JAVA2D renderer would happen to be faster than the P2D 1! 🤷‍♂️  
But the king of performance is the FX2D renderer FYI: 👑  
`size(800, 700, FX2D);`

> **[size() / Reference](https://processing.org/reference/size_.html)**
>
> Defines the dimension of the display window width and height in units of pixels. In a program that has the setup() function, the size() function must be the first line of code inside …

[http://processing.github.io/processing-javadocs/core/processing/core/PConstants.html#FX2D](http://processing.github.io/processing-javadocs/core/processing/core/PConstants.html#FX2D)

---

<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:** [September 17, 2020, 8:15am UTC](https://discourse.processing.org/t/why-p2d-is-slower-than-default-renderer/23897/3 "2020-09-17T08:15:01Z")

</div>

The answer is quite simple - P2D and P3D use OpenGL which is very slow rendering lines and very fast at filling areas so change the display method in Bubble class to

```auto
  void display() {
    fill(c);
    noStroke();
    circle(x, y, 2*r);
  }

```

and P2D simply flies 🙂

---

<div class="post-metadata">

**Author:** ![neilcsmith](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/neilcsmith/32/144_2.png) [@neilcsmith](https://discourse.processing.org/u/neilcsmith)\
**Post date:** [September 17, 2020, 9:37am UTC](https://discourse.processing.org/t/why-p2d-is-slower-than-default-renderer/23897/4 "2020-09-17T09:37:39Z")

</div>

> [@quark](#):
>
> P2D and P3D use OpenGL which is very slow rendering lines and very fast at filling areas

That’s part of it, but this is also due to the implementation of line drawing in `P2D` which favours accuracy over performance. There’s a bit more info in [Performance troubles in P2D](https://github.com/processing/processing/issues/5256) that’s worth a read. There’s an out of date code branch somewhere based on that issue - keep meaning to try updating it for latest Processing.

It’s stroke weights higher than 1 that are particularly affected. The default stroke weight keeps to 60fps easy here.

Incidentally, another workaround with `P2D` is to do -

```java
void display() {
  noStroke();
  fill(0);
  circle(x, y, 2*r+1);
  fill(c);
  circle(x, y, 2*r);
}

```

---

<div class="post-metadata">

**Author:** ![IpNeNaEcRe](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/ipnenaecre/32/11223_2.png) [@IpNeNaEcRe](https://discourse.processing.org/u/IpNeNaEcRe)\
**Post date:** [September 17, 2020, 2:51pm UTC](https://discourse.processing.org/t/why-p2d-is-slower-than-default-renderer/23897/5 "2020-09-17T14:51:39Z")

</div>

Thanks, the **FX2D** is truly the king!!!  
Like Neilcsmith and Quark said, it is the **stroke weight** makes the difference. Particularly when **stroke weight** higher than 1(default stroke weight).  
I did some test, this is the number of bubbles makes the FPS slower than 30 in diffrent renderer and stroke weight.

| Renderer | strokeWeight(2) | strokeWeight(1) | noStroke() |
| --- | --- | --- | --- |
| Default | 3k | 3k | 9k |
| P2D | 0.3k | 7k | 17k |
| P3D | 5.5k | 7k | 17k |
| FX2D | 100k | 100k | 250k |

---

<div class="post-metadata">

**Author:** ![IpNeNaEcRe](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/ipnenaecre/32/11223_2.png) [@IpNeNaEcRe](https://discourse.processing.org/u/IpNeNaEcRe)\
**Post date:** [September 17, 2020, 2:54pm UTC](https://discourse.processing.org/t/why-p2d-is-slower-than-default-renderer/23897/6 "2020-09-17T14:54:40Z")

</div>

Great answer! Thanks!

---

<div class="post-metadata">

**Author:** ![neilcsmith](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/neilcsmith/32/144_2.png) [@neilcsmith](https://discourse.processing.org/u/neilcsmith)\
**Post date:** [September 19, 2020, 8:20am UTC](https://discourse.processing.org/t/why-p2d-is-slower-than-default-renderer/23897/7 "2020-09-19T08:20:21Z")

</div>

> [@IpNeNaEcRe](#):
>
> Thanks, the **FX2D** is truly the king!!!

This has been bugging me, because frankly I don’t believe the figures - I think there’s more to it. One thing to be aware of with JavaFX is that unlike the OpenGL pipelines it’s not single threaded. Something that has caused a whole lot of issues with a recent client project I did, and I think is behind those figures - they’re going to be different, but not _that_ different.

With P2D and P3D all your calculations and rendering happen on the animation thread. With JavaFX, drawing calls are batched up, then another thread handles rendering asynchronously. I have a feeling your figures might be reflecting just the framerate of batching up the data, not actually rendering it to the screen. It’s likely JavaFX is just throwing some frames away.

Note also this from the Javadoc of the JavaFX [GraphicsContext](https://docs.oracle.com/javase/8/javafx/api/javafx/scene/canvas/GraphicsContext.html) used by Processing -

> Each call pushes the necessary parameters onto the buffer where they will be later rendered onto the image of the Canvas node by the rendering thread at the end of a pulse.

---

<div class="post-metadata">

**Author:** ![IpNeNaEcRe](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/ipnenaecre/32/11223_2.png) [@IpNeNaEcRe](https://discourse.processing.org/u/IpNeNaEcRe)\
**Post date:** [September 19, 2020, 5:17pm UTC](https://discourse.processing.org/t/why-p2d-is-slower-than-default-renderer/23897/8 "2020-09-19T17:17:58Z")

</div>

> [@neilcsmith](#):
>
> I have a feeling your figures might be reflecting just the framerate of batching up the data, not actually rendering it to the screen. It’s likely JavaFX is just throwing some frames away.

😅 I’m just a beginner, don’t know much about the principles behind it.

When I test it, I set the for loop to increase 1000 bubbles a click. With other renderer, the animation soon get slower. FX2D just get stuck a while when I increase the bubbles, then the screen looks fluently as the animation runs beginning.

---

<div class="post-metadata">

**Author:** ![neilcsmith](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/neilcsmith/32/144_2.png) [@neilcsmith](https://discourse.processing.org/u/neilcsmith)\
**Post date:** [September 21, 2020, 10:12am UTC](https://discourse.processing.org/t/why-p2d-is-slower-than-default-renderer/23897/9 "2020-09-21T10:12:33Z")

</div>

> [@IpNeNaEcRe](#):
>
> 😅 I’m just a beginner, don’t know much about the principles behind it.

No problem! In general, if you get outlier figures, always question why. Like you did with P2D, and the issue linked before is _probably_ the cause there.

With FX2D, why would it be _so_ much different? The _possible_ answer is always that you’re not measuring what you think you are. Unlike the other renderers, I don’t think Processing’s framerate value with FX2D is really the number of frames being rendered per second. For that I think you’d need to get the value directly from JavaFX itself, and offhand I can’t remember an easy way to do that.
