PGraphics.beginDraw(), PGraphics.endDraw() alternatives

are there any alternatives to beginDraw() and endDraw()?

as using beginDraw and endDraw are expensive

if i do

    graphics.endDraw();
    if (displayFPS) {
      window.graphics.beginDraw();
      int oldColor = window.graphics.fillColor;
      window.graphics.fill(255);
      window.graphics.textSize(16);
      window.graphics.text("FPS: " + frameRate, 10, 20);
      window.graphics.fill(oldColor);
      window.graphics.endDraw();
    }
    graphics.beginDraw();
    graphics.image(
      window.graphics,
      window.x,
      window.y,
      window.width,
      window.height
    );

then i get 31 to 32 FPS but if i do

    graphics.endDraw();
    if (displayFPS) {
      window.graphics.beginDraw();
      int oldColor = window.graphics.fillColor;
      window.graphics.fill(255);
      window.graphics.textSize(16);
      window.graphics.text("FPS: " + frameRate, 10, 20);
      window.graphics.fill(oldColor);
      window.graphics.endDraw();
    }
    graphics.beginDraw();
    graphics.endDraw();   // 1
    graphics.beginDraw(); // 1
    graphics.endDraw();   // 2
    graphics.beginDraw(); // 2
    graphics.endDraw();   // 3
    graphics.beginDraw(); // 3
    graphics.endDraw();   // 4
    graphics.beginDraw(); // 4
    graphics.endDraw();   // 5
    graphics.beginDraw(); // 5
    graphics.endDraw();   // 6
    graphics.beginDraw(); // 6
    graphics.endDraw();   // 7
    graphics.beginDraw(); // 7
    graphics.endDraw();   // 8
    graphics.beginDraw(); // 8
    graphics.image(
      window.graphics,
      window.x,
      window.y,
      window.width,
      window.height
    );

then i get 16.0 FPS

What are you trying to achieve?

You write directly to the screen, using text() etc. directly OR make a PGraphics object pg and use this. See reference

im trying to find away to reduce the amount of beginDraw()/endDraw() calls that i need, specifically see Scoped beginDraw and endDraw

but mainly, my issue is when i have A LOT of PGraphics objects all being rendered to my screen, my FPS will plummet due to the expensive beginDraw() endDraw() calls being called for each PGraphics object i draw and image(pGraphicsObject); / pGraphicsObject.image(pGraphicsObjectChild);

Why don’t you draw directly on the screen?

because im designing this to be modular, mainly for a window manager, where, if desired, the user can override the default window manager class provided in order to provide their own custom window manager, as well as add their own custom *sketches* into the window manager at runtime, such as an audio player application sketch and an internet sketch (if such is creatable)

in which:
the compositor contains x1 PGraphics
the window manager contains x1 PGraphics
the application contains x1 PGraphics

PGraphics is primarily used in order to obtain off-screen rendering (which is required if, for example, an application gets minimized), also it makes things a ton easier as i can just image(applicationWindowImage, X, Y); instead of trying to complicatedly get the application to draw specifically at X,Y and a bunch of other stuff that is probably introduced by on-screen rendering

HOWEVER the only downside to this is that PGraphic’s beginDraw and endDraw calls are expensive if called lots

1 Like

PImage doesn’t have those methods. Only PGraphics does.

Each PGraphics is a full buffered canvas object. If you make a lot of those, you are copying a lot of pixels around. Two ways to mix that with performance are to 1) have fewer layers (fewer PGraphics) and composite into them, and 2) have multiple objects draw in consolidated batches – try to have only one endDraw() per canvas per frame.

So when you say “i have A LOT of PGraphics objects” it sounds like you are trying to give each window its own full canvas. Maybe don’t do that. Instead, have a window layer, give windows a z-order, and let them draw into that layer however they want. So, you might declare a window like this:

class Window() {
  PGraphics canvas;
  Window(PGraphics canvas, String id, int w, int h) {
    this.canvas = canvas;
  }
}

…and in a multi-desktop setup, there would be two canvas PGraphics instead of one, but under normal circumstances all windows would share the same canvas.

This is almost identical to the pattern that Processing libraries use. Most Processing libraries are declared with

class MyLibrary {
  PApplet pa;
  MyLibrary(Papplet pa, String whatever) {
    this.pa = pa;
  }
}

…and then they each access the Processing shared canvas using pa.g. Then you can extend PeasyCam or ControlP5 classes and mix them in one sketch with one final output without each individual library object needing its own canvas.

1 Like

This is a good point, design-wise. Keep in mind that whatever you are doing to draw to the applicationWindowImage internal PGraphics – call it .render() – you could also draw to the canvas, e.g. with applicationWindow.render(x, y). If the .render() is drawing to an internal PGraphics pg, then the signature could also accept either the sketch canvas or the internal buffer, and you can switch back and forth for active windows or passive etc. by passing your method g.

class ApplicationWindow {
  // ...
  void render(x, y) {
    // default is the internal canvas
    render(this.pg, x, y);
  }
  void render(PApplet pg, x, y) {
    // accepts either the internal PGraphics
    // or the PApplet.g canvas
  }
}

hmmm ok, ill try that

also see Off-screen render performance, multiple PGraphics objects and Shared PGraphics instances - drawing

but ummmm… how would i go about seperation? as canvas.fill(0); in an application would fill the canvas in ALL applications since it is shared, right? if so, could i use PGraphics.clip(x1, y1, x2, y2) to implement a global drawing canvas?

i also tried Clip not behaving as expected in relation to graphic transformations (eg rotateX) but it didnt work as expected (failed horribly)

fill() sets the current fill color on the style stack.

If you want to isolate uses of it, use pushStyle() and popStyle() – that pushes your fill color onto the stack while one object / method is drawing, then pops the color off when you are done.

I’m not quite sure I understand what you mean – you can use it to limit drawing areas, yes
Keep in mind that clip only changes which pixels areas are drawn to – it doesn’t do anything else, so 2D transforms / rotations / styling / etc. are still a set of global states within the canvas / PGraphics that you need to manage with the matrix and style stacks.

ok, but ummm how would i go about preventing the method from clipping out of bounds?