# Performance loss with PGraphics and SVG

**URL:** <https://discourse.processing.org/t/performance-loss-with-pgraphics-and-svg/12897>\
**Category:** Coding Questions\
**Created:** [July 22, 2019, 8:25pm UTC](https://discourse.processing.org/t/performance-loss-with-pgraphics-and-svg/12897 "2019-07-22T20:25:13Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![eduzal](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/eduzal/32/759_2.png) [@eduzal](https://discourse.processing.org/u/eduzal)\
**Post date:** [July 22, 2019, 8:25pm UTC](https://discourse.processing.org/t/performance-loss-with-pgraphics-and-svg/12897/1 "2019-07-22T20:25:13Z")

</div>

Hi there. I’m having a large issue with performance loss using PGraphics.  
The situation is: I’m importing an svg with 860 child Polygons. I need to do a color sampling for each and every child shape based on it’s centroid. The final file is of large dimension(2400,1920).

What i have now: when i get everything running outside the PGr i get over 45 frames/second. if i encapsulate it in a PGr i get 9 and it starts to decrease the frameRate. So actualy i get no performance enhancement for offscreen buffer.

P.S. I have 10 images for colorsampling, the images are full scale(2400,1920). in the next phase it will be a video, a shader, or another interaction.

where did i get it worng?

here’s the code. PGr operations are commented

```auto
import java.util.Map;
ArrayList<Brick> bricks;
HashMap<Brick, Integer> colorMap;

PShape original;
PGraphics pg;
PImage[] images=new PImage[10];
int imageIndex=6;
PImage colorSampler;

int w=2400;
int h=1920;

void setup() {
  size(1200, 960, P2D);
  smooth(8);
  frameRate(30);

  pg=createGraphics(w, h);
  colorSampler=createImage(w, h, RGB);
  loadImages();
  colorSampler=images[imageIndex];

  bricks=new ArrayList<Brick>();
  buildBrick();
  colorMap=new HashMap<Brick, Integer>();
  buildColorMap();
  getColor();

}

void draw() {

  image(colorSampler, 0, 0);

  //pg.beginDraw();
  //pg.clear();

  getColor();

  for (Brick b:bricks) {
    b.update();
    b.display();
  }

 //pg.endDraw();

  fill(255, 0, 0, 100);
  text(frameRate, 10, 10);
}

void buildBrick() {
  original=loadShape("tijolos2.svg");
  original.disableStyle();
  int id=0;
  int numChild=original.getChildCount();
  println(numChild);

  for (int i=0; i<numChild; i++) {
    PShape tempFace=original.getChild(i);
    int numBricks=tempFace.getChildCount();

    for (int j=0; j<numBricks; j++) {
      PShape temp=tempFace.getChild(j);

      bricks.add(new Brick(id));

      int vCount=temp.getVertexCount();

      for (int k=0; k<vCount; k++) {
        Brick b=bricks.get(bricks.size()-1);
        PVector pv=temp.getVertex(k);
        b.addPoint(pv);
      }

      Brick b=bricks.get(bricks.size()-1);
      b.getCentroid();
      b.buildShape();

      id++;
    }
  }
}

void buildColorMap() {
  for (Brick b : bricks) {
    colorMap.put(b, b.c);
  }
}

void getColor() {
  colorSampler.loadPixels();

  for (Brick b : bricks) {
    color c=color(red(colorSampler.pixels[b.loc]), green(colorSampler.pixels[b.loc]), blue(colorSampler.pixels[b.loc]));
    colorMap.put(b, c);
  }
}

void loadImages() {
  for (int loadCounter=1; loadCounter<=10; loadCounter++) { 
    images[loadCounter-1]=loadImage("sample0"+loadCounter+".jpg");
  }
}

void keyPressed() {
  if (key==CODED) {
    if (keyCode==RIGHT) {
      if (imageIndex<images.length-1) {
        imageIndex++;
      } else {
        imageIndex=0;
      }
      println("RIGHT: "+imageIndex);
      colorSampler=images[imageIndex];
    }
    if (keyCode==LEFT) {
      if (imageIndex>0) {
        imageIndex--;
      } else {
        imageIndex=images.length-1;
      }
      println("LEFT: "+imageIndex);
      colorSampler=images[imageIndex];
    }
  }
}

```

Brick object

```auto
class Brick {
  PShape s, centroid;
  ArrayList<PVector> vertices;
  PVector center;
  int centerX, centerY;
  int id;
  color c;
  int loc;

  Brick(int _id) {
    s=createShape();
    vertices=new ArrayList<PVector>();
    center=new PVector();
    id=_id;
    c=color(0);
  }

  void addPoint(PVector p) {
    vertices.add(p);
  }

  void getCentroid() {
    for (PVector p : vertices) {
      centerX+=p.x;
      centerY+=p.y;
    }
    centerX/=vertices.size();
    centerY/=vertices.size();

    loc=int(centerX+centerY*colorSampler.width);
  }

  void buildShape() {
    s.beginShape();
    s.fill(c, 120);
    s.strokeWeight(1);
    s.stroke(255);
    for (PVector p : vertices) {
      s.vertex(p.x, p.y);
    }
    s.endShape(CLOSE);

    centroid=createShape(ELLIPSE, centerX, centerY, 8, 8);
  }

  void update() {
    c=colorMap.get(this);
  }

  void display() {
    /*
    pg.beginDraw(); 
    pg.strokeWeight(1);
    s.setFill(color(c, 150));
    pg.shape(s);

    pg.strokeWeight(4);
    centroid.setStroke(color(255));
    centroid.setFill(color(c));
    pg.shape(centroid);

    pg.endDraw();
    */

    strokeWeight(1);
    s.setFill(color(c, 150));
    shape(s);

    strokeWeight(4);
    centroid.setStroke(color(255));
    centroid.setFill(color(c));
    shape(centroid);
  }
}

```

---

<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:** [July 23, 2019, 9:33am UTC](https://discourse.processing.org/t/performance-loss-with-pgraphics-and-svg/12897/2 "2019-07-23T09:33:11Z")

</div>

> [@eduzal](#):
>
> pg=createGraphics(w, h);

Try `createGraphics(w, h, P2D);`

---

<div class="post-metadata">

**Author:** ![eduzal](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/eduzal/32/759_2.png) [@eduzal](https://discourse.processing.org/u/eduzal)\
**Post date:** [July 23, 2019, 4:36pm UTC](https://discourse.processing.org/t/performance-loss-with-pgraphics-and-svg/12897/3 "2019-07-23T16:36:38Z")

</div>

no difference at all

---

<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:** [July 23, 2019, 4:44pm UTC](https://discourse.processing.org/t/performance-loss-with-pgraphics-and-svg/12897/4 "2019-07-23T16:44:22Z")

</div>

OK, just an obvious potential problem / difference, because one is using Java2D and one is using P2D.

---

<div class="post-metadata">

**Author:** ![eduzal](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/eduzal/32/759_2.png) [@eduzal](https://discourse.processing.org/u/eduzal)\
**Post date:** [September 12, 2019, 7:11pm UTC](https://discourse.processing.org/t/performance-loss-with-pgraphics-and-svg/12897/5 "2019-09-12T19:11:25Z")

</div>

still don’t get where the problem lies, since i’m not using svg in runtime, but an arraylist of polylines that contains one arraylist of PVectors and 6 vectors is the greatest of them all.

---

<div class="post-metadata">

**Author:** ![hamoid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hamoid/32/58_2.png) [@hamoid](https://discourse.processing.org/u/hamoid)\
**Post date:** [September 12, 2019, 9:33pm UTC](https://discourse.processing.org/t/performance-loss-with-pgraphics-and-svg/12897/6 "2019-09-12T21:33:09Z")

</div>

Do you need to do everything you are doing inside `draw()` on every frame? Or can some of those calculations be done once inside `setup()`?

This is not very fast:

```
 color c=color(red(colorSampler.pixels[b.loc]), green(colorSampler.pixels[b.loc]), blue(colorSampler.pixels[b.loc]))

```

Why not just

```
 color c=colorSampler.pixels[b.loc];

```

? If you need each component, look in the documentation of `red()`, `green()` and `blue()` for faster bit-shifting based alternatives.

If your main screen is 1200x960, why do you need the 10 other images to be 2400x1920?

---

<div class="post-metadata">

**Author:** ![eduzal](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/eduzal/32/759_2.png) [@eduzal](https://discourse.processing.org/u/eduzal)\
**Post date:** [September 12, 2019, 11:26pm UTC](https://discourse.processing.org/t/performance-loss-with-pgraphics-and-svg/12897/7 "2019-09-12T23:26:17Z")

</div>

hi  
1.  
i’m trying to use video or a live feed to do the color sampling. with still images, color sampling just needs to happen once.

1. tried the second option also with no gain at all

2. 

my final output will be a 2400x1920 screen(two vertical rotated 90º)

till now, i’m trying the render solution instead of a live one. with render i mean saving each frame.

---

<div class="post-metadata">

**Author:** ![eduzal](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/eduzal/32/759_2.png) [@eduzal](https://discourse.processing.org/u/eduzal)\
**Post date:** [September 12, 2019, 11:41pm UTC](https://discourse.processing.org/t/performance-loss-with-pgraphics-and-svg/12897/8 "2019-09-12T23:41:22Z")

</div>

but just in case. performance sucks anyway, even when not calling the color sampling.  
just plain svg runs at 44fps instead of the usual 60

---

<div class="post-metadata">

**Author:** ![hamoid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hamoid/32/58_2.png) [@hamoid](https://discourse.processing.org/u/hamoid)\
**Post date:** [September 12, 2019, 11:51pm UTC](https://discourse.processing.org/t/performance-loss-with-pgraphics-and-svg/12897/9 "2019-09-12T23:51:33Z")

</div>

It’s hard to suggest something without understanding the logic 🙂 In the final program… there will be a video instead of 10 images? What’s the purpose of the svg? What is the goal of the program?

You can profile the application using [https://visualvm.github.io/](https://visualvm.github.io/) and it could tell which methods are consuming most CPU.

By looking at another of your questions I get the impression you were using openFrameworks before. Why did you switch (if you did)?

---

<div class="post-metadata">

**Author:** ![hamoid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hamoid/32/58_2.png) [@hamoid](https://discourse.processing.org/u/hamoid)\
**Post date:** [September 12, 2019, 11:54pm UTC](https://discourse.processing.org/t/performance-loss-with-pgraphics-and-svg/12897/10 "2019-09-12T23:54:46Z")

</div>

Hmmm but the svg is not going to change on every frame right? Could you draw it into a PGraphics just once, so you work with pixels instead of rendering vector graphics to pixels on every frame?

---

<div class="post-metadata">

**Author:** ![eduzal](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/eduzal/32/759_2.png) [@eduzal](https://discourse.processing.org/u/eduzal)\
**Post date:** [September 13, 2019, 1:29am UTC](https://discourse.processing.org/t/performance-loss-with-pgraphics-and-svg/12897/11 "2019-09-13T01:29:20Z")

</div>

the objective is to do a live mapping on a weird surface.  
i’ve got a gothic dome that is make of bricks. each shape is a brick. all 880 bricks/shapes are in the vector file. i’m projecting over these bricks with two projectors. my workflow is generative -\> syphon -\> madmapper.  
so for instance, i can project something like a growing circle, or a particle system that emits circles that grow. i can simply do that. but instead i can light up the brick if some part of the circunference is passing through the brick centroid. actually this is what i’m doing. but i have to render the videos instead of doing something live(vj).  
i’d rather do something live/generative than doing renders. after all, this is why i’ve migrated to programming.  
i learned to program with processing, so this is the environment where i work faster. openFramworks is awesome, but i’m slow with it, i get lost in how to do things instead of doing things. i intend to prototype in processing than translate it to oF.

following images are what madmapper spatial scan delivers. one for each projector  
projector1

 ![cripta5_P1](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/c/c2f3a47031038b7d527e16a02b42b6f24cc90d08.jpeg)  
projector 2  
 ![cripta5_P2](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/5/567064689f6ffb45913b339e8b71dc991a19cb95.jpeg)

---

<div class="post-metadata">

**Author:** ![eduzal](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/eduzal/32/759_2.png) [@eduzal](https://discourse.processing.org/u/eduzal)\
**Post date:** [September 13, 2019, 1:29am UTC](https://discourse.processing.org/t/performance-loss-with-pgraphics-and-svg/12897/12 "2019-09-13T01:29:37Z")

</div>

also. the same svg gets 44fps in oF too.

---

<div class="post-metadata">

**Author:** ![hamoid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hamoid/32/58_2.png) [@hamoid](https://discourse.processing.org/u/hamoid)\
**Post date:** [September 13, 2019, 8:54am UTC](https://discourse.processing.org/t/performance-loss-with-pgraphics-and-svg/12897/13 "2019-09-13T08:54:18Z")

</div>

In debug or release mode? Release can perform much faster.

---

<div class="post-metadata">

**Author:** ![hamoid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hamoid/32/58_2.png) [@hamoid](https://discourse.processing.org/u/hamoid)\
**Post date:** [September 13, 2019, 9:03am UTC](https://discourse.processing.org/t/performance-loss-with-pgraphics-and-svg/12897/14 "2019-09-13T09:03:42Z")

</div>

I would use visualvm to find the bottleneck. Otherwise you can do random attempts at optimizing, but you may or may not find the bottleneck.

Random ideas:

- Check how many vertices each brick has. Maybe they are too detailed.
- Does the computer have good CPU and GPU?
- Do you need `stroke()` in the bricks? That involves more work than just `fill()`
- Calling `color()` each time is not necessary if the color doesn’t change (for instance you could store `color(255)` in a variable called white.
- I believe calling `.setStroke()` and `.setFill()` iterates over each vertex and changes its properties. Using a shader to affect rendering might be faster (if the bottleneck is CPU bound).

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [September 14, 2019, 11:27pm UTC](https://discourse.processing.org/t/performance-loss-with-pgraphics-and-svg/12897/15 "2019-09-14T23:27:13Z")

</div>

I’m going to hazard a guess – just a guess! – that you could get a large performance boost by ditching the PShape Brick.s and the use of shape() in Brick.display() entirely, and switching to just keeping the vertex list and using quad().

[https://processing.org/reference/quad\_.html](https://processing.org/reference/quad_.html)

---

<div class="post-metadata">

**Author:** ![eduzal](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/eduzal/32/759_2.png) [@eduzal](https://discourse.processing.org/u/eduzal)\
**Post date:** [September 16, 2019, 3:48pm UTC](https://discourse.processing.org/t/performance-loss-with-pgraphics-and-svg/12897/16 "2019-09-16T15:48:26Z")

</div>

i tought that if i built the brick once, and then display it i wouldn’t loose performance by building the brick every cycle.  
quad might work, but sometimes, specially in the corners i have three, fice or six vertices per brick.

---

<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 16, 2019, 4:05pm UTC](https://discourse.processing.org/t/performance-loss-with-pgraphics-and-svg/12897/17 "2019-09-16T16:05:31Z")

</div>

You get most performance from cached shapes when you draw them in one go under one parent, rather than drawing lots of small ones individually. Simpler shapes will probably draw quicker without using PShape.

Can you replace the color map entirely with texture coordinates on the vertexes for each brick to read from the color? Or with custom attributes and shaders. Let the GPU do the work.

---

<div class="post-metadata">

**Author:** ![eduzal](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/eduzal/32/759_2.png) [@eduzal](https://discourse.processing.org/u/eduzal)\
**Post date:** [September 16, 2019, 4:16pm UTC](https://discourse.processing.org/t/performance-loss-with-pgraphics-and-svg/12897/18 "2019-09-16T16:16:26Z")

</div>

i still lack the knowledge to create my own custom shaders. and i agree it would be much faster to get the color for each desired coordinate from shaders.

---

<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 16, 2019, 4:17pm UTC](https://discourse.processing.org/t/performance-loss-with-pgraphics-and-svg/12897/19 "2019-09-16T16:17:54Z")

</div>

If it’s just the colour from an input texture, you should be able to do this with texture coordinates on the vertexes of the shape and no custom shader though.

---

<div class="post-metadata">

**Author:** ![eduzal](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/eduzal/32/759_2.png) [@eduzal](https://discourse.processing.org/u/eduzal)\
**Post date:** [September 16, 2019, 5:20pm UTC](https://discourse.processing.org/t/performance-loss-with-pgraphics-and-svg/12897/20 "2019-09-16T17:20:08Z")

</div>

will have to read how to get this done.

[Next page](https://discourse.processing.org/t/performance-loss-with-pgraphics-and-svg/12897.md?page=2)
