public void display() {
    // Create autorelease pool per frame to avoid possible deadlock
    // situations
    // because there are 3 CAMetalDrawables sitting in an autorelease pool.

    try (NSAutoreleasePool pool = new NSAutoreleasePool()) {
      // handle display changes here
      if (layerSizeDidUpdate) {
        // set the metal layer to the drawable size in case orientation
        // or size changes
        CGSize drawableSize = getBounds().getSize();
        drawableSize.setWidth(drawableSize.getWidth() * this.getContentScaleFactor());
        drawableSize.setHeight(drawableSize.getHeight() * this.getContentScaleFactor());

        metalLayer.setDrawableSize(drawableSize);

        // renderer delegate method so renderer can resize anything if
        // needed
        delegate.reshape(this);

        layerSizeDidUpdate = false;
      }

      // rendering delegate method to ask renderer to draw this frame's
      // content
      delegate.render(this);

      // do not retain current drawable beyond the frame.
      // There should be no strong references to this object outside of
      // this view class
      ((NSObject) currentDrawable).dispose();
      currentDrawable = null;
    }
  }
  public void computeConstantSize() {
    CGSize minSize = CGSize.Zero();
    CGSize intrinsicSize = CGSize.Zero();

    for (Drawable drawable : drawables) {
      CGSize min = drawable.getMinimumSize();
      CGSize intrinsic = drawable.getIntrinsicSize();

      if (min.getWidth() > minSize.getWidth()) minSize.setWidth(min.getWidth());
      if (min.getHeight() > minSize.getHeight()) minSize.setHeight(min.getHeight());

      if (intrinsic.getWidth() > intrinsicSize.getWidth())
        intrinsicSize.setWidth(intrinsic.getWidth());
      if (intrinsic.getHeight() > intrinsicSize.getHeight())
        intrinsicSize.setHeight(intrinsic.getHeight());
    }

    this.constantIntrinsicSize = intrinsicSize;
    this.constantMinimumSize = minSize;
    this.constantSizeComputed = true;
  }