Full Screen application performance

what would some techiques be for optiming full screen application performance? in particular with a lot of image(PGraphicsObjectInstance) calls

with a 400x400 size and 4 Window objects being rendered i can achieve 60FPS average even when moving a window

however with fullscreen, with zero rendered i get 50 to 60 FPS, with 1 i get 51 FPS, with 4 i get 38 FPS, and this drops to 4 FPS when i move a window

for example

having a single Window

which is 1 graphics object (Window), rendered onto a parent graphics object (WindowObject), rendered onto a parent graphics object (Compositor) and finally rendered onto the surface (PApplet)

via image(graphics) -> graphics.image(graphics, ...)

drops my FPS from 60 to 51

and with 4 Windows it drops to 30 FPS

Compositor.<call>() -> WindowObject[<number>].<call>() -> Window.<call>();

eg Compositor.draw() -> { WindowObject[0].draw() -> Window.draw() };

for example, a typical draw() call looks like this

  1. *.draw
void draw() {
  compositor.draw();
}
  1. Compositor.draw
class Compositor {
  void draw() {
    graphics.beginDraw();
    graphics.background(0);
    for (WindowObject window: windows) {
      window.draw();
      drawGraphics(window);
    }
    graphics.endDraw();
    drawGraphics();
  }

  void drawGraphics() {
    if (displayFPS) {
      graphics.beginDraw();
      int oldColor = graphics.fillColor;
      graphics.fill(255);
      graphics.textSize(16);
      graphics.text("FPS: " + frameRate, 10, 20);
      graphics.fill(oldColor);
      graphics.endDraw();
    }
    image(graphics, 0, 0);
  }

  void drawGraphics(WindowObject window) {
    graphics.image(
      window.graphics,
      window.x,
      window.y,
      window.previewWidth,
      window.previewHeight
    );
  }
}
  1. WindowObject.draw
class WindowObject {
  void draw() {
    correctMouseLocation();
    window.draw();
    drawWindow();
  }
  void drawGraphics() {
    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
    );
    graphics.endDraw();
  }
  
  void drawWindow() {
    clearScreen();
    if (focus) {
      if (clickedOnBorder && locked) drawBordersLocked();
      else drawBordersHighlighted();
    } else {
      drawBorders();
    }
    drawGraphics();
  }
}
  1. Window.draw
class Window {
  public PGraphics graphics = null;
  
  int height;
  int width;
  int x, y;
  int mouseX, mouseY;
  Window() {} // implicit super constructor required
  void onBeforeResize() {}
  String onRequestType() { return P3D; }
  void onAfterResize() {}
  void setup() {
    graphics.beginDraw();
    graphics.background(0);
    graphics.endDraw();
  }
  void draw() {
    graphics.beginDraw();
    graphics.background(0);
    graphics.endDraw();
  }
  void mousePressed() {}
  void mouseDragged() {}
  void mouseReleased() {}
  void mouseMoved() {}
}
  1. {* extends Window}.draw
class Applications_Cube extends Window {
  
  @Override
  void draw() {
    graphics.beginDraw();
    graphics.lights();
    graphics.background(0);
    graphics.noStroke();
    graphics.translate(width/2, height/2);
    graphics.rotateX(frameCount/100.0);
    graphics.rotateY(frameCount/200.0);
    graphics.box(40);
    graphics.endDraw();
  }
}

FILES/CODE:

Compositor compositor;

void settings() {
  fullScreen(P3D);
  //size(400, 400, P3D);
}

void addApplications() {
  compositor.add(new Applications_DraggableExample(), 200, 200);
  compositor.setLocation(0, 0);
  compositor.add(new Applications_Cube(), 200, 200);
  compositor.setLocation(0, 200);
  compositor.add(new Applications_XCursor_Decoder_Example(), 200, 200);
  compositor.setLocation(200, 0);
  compositor.add(new Applications_Cube(), 200, 200);
  compositor.setLocation(200, 200);
}

void setup() {
  compositor = new Compositor(width, height);
  compositor.displayFPS = true;
  compositor.displayWindowFPS = true;
  compositor.debug = false;
  addApplications();
  compositor.setup();
}

void draw() {
  compositor.draw(); //<>// //<>//
}

void mousePressed() {
  compositor.mousePressed();
}

void mouseDragged() {
  compositor.mouseDragged();
}

void mouseReleased() {
  compositor.mouseReleased();
}

void mouseMoved() {
  compositor.mouseMoved();
}

Runs alright for me (1920x1080). Is your PC just terrible?

I once did a similar thing (running multiple sketches within one sketch) and got hammered by the resize() function, since each sketch would first draw into a buffer the size of the Processing window and then be resized to the size of it’s internal window. If you’re not resizing (rather, your buffer is the size of the window), then it’s hard to think of any possible performance improvements.

I once did a similar thing (running multiple sketches within one sketch) and got hammered by the resize() function, since each sketch would first draw into a buffer the size of the Processing window and then be resized to the size of it’s internal window.

damn, mine just draws directly into a PGraphics and recreates it with the specified window dimensions upon resize, with a preview scaling displayed during the resize operation, saves alot of cpu as opposed to just drawing the full texture then downscaling it

  void mouseReleased() {
    if (clickedOnResizeBorder) {
      if (mouseDragType != MOUSE_CLICKED_NOTHING) {
        if (
          clickedResizeType == MOUSE_CLICKED_RESIZE_LEFT ||
          clickedResizeType == MOUSE_CLICKED_RESIZE_RIGHT
        ) {
          windowResize(previewWidth, height);
        } else if (
          clickedResizeType == MOUSE_CLICKED_RESIZE_TOP ||
          clickedResizeType == MOUSE_CLICKED_RESIZE_BOTTOM
        ) {
          windowResize(width, previewHeight);
        } else if (
          clickedResizeType == MOUSE_CLICKED_RESIZE_TOP_LEFT ||
          clickedResizeType == MOUSE_CLICKED_RESIZE_TOP_RIGHT ||
          clickedResizeType == MOUSE_CLICKED_RESIZE_BOTTOM_LEFT ||
          clickedResizeType == MOUSE_CLICKED_RESIZE_BOTTOM_RIGHT
        ) {
          windowResize(previewWidth, previewHeight);
        }
        resizeWindow();
        graphics = createGraphics(width, height, P3D);
      }
      clickedOnResizeBorder = false;
      resizing = false;
      resizingLeft = false;
      resizingTop = false;
      resizingRight = false;
      resizingBottom = false;
      resizingTopLeft = false;
      resizingTopRight = false;
      resizingBottomLeft = false;
      resizingBottomRight = false;
      clickedResizeType = MOUSE_CLICKED_NOTHING;
    } else if (clickedOnBorder) {
      ct.loadCursor("cursors/aerodrop/4498f0e0c1937ffe01fd06f973665830");
      clickedOnBorder = false;
      locked = false;
    } else if (clickedOnApp) {
      clickedOnApp = false;
      correctMouseLocation();
      window.mouseReleased();
    }
    drawWindow();
  }

im using a Macbook Pro mid-2012 (MacBookPro92)

0 windows, 60 FPS

1 window - 52 FPS

2 windows - 40 FPS

3 windows - 33 FPS

4 windows - 28 FPS

16 windows - 11 fps

im using a Macbook Pro mid-2012 (MacBookPro92)
No wonder…:rofl:

whats so bad about that?

It’s an 8-year-old laptop processor. Of course it sucks.

oof, how can i optimize for low-end/mid-end (can play gta 5 at 11 fps in fullscreen lol) GPU/CPU’s lmao (intel i5 CPU)

Hey, this is probably a little late but I’m also trying to do the exact same thing right now. I’ve been making a windowed environment and something that’s been killing me for ages is that I can’t figure out how to mask out the window contents but still have a sketch that can run in real time. So far I’ve been using PGraphics objects like you, but using some altered drawing functions that take into account how much the PGraphics object is being scaled so I don’t have to call resize() as much.