LWJGL2 / OSX: Collection was mutated while being enumerated

Started by 3xp0n3nt, October 17, 2016, 22:19:53

Previous topic - Next topic

3xp0n3nt

LWJGL 2.9.2 (via LibGDX 1.9.5-SNAPSHOT)
OSX 10.11.6 (El Capitan)
Java 1.8.0_72-b15

The following native crash (sporadically) occurs while changing display mode from:

System.setProperty("org.lwjgl.opengl.Window.undecorated", true);
Display.setDisplayMode(DisplayMode: 900x600x0@0Hz)
Display.setFullscreen(false);
Display.setResizable(false);
Display.getDesktopDisplayMode(): 1920x1080x32@60Hz


to:

System.setProperty("org.lwjgl.opengl.Window.undecorated", false);
Display.setDisplayMode(DisplayMode: 1920x1080x0@0Hz)
Display.setFullscreen(false);
Display.setResizable(true);
Display.getDesktopDisplayMode(): 1920x1080x32@60Hz


java[1450:32253] *** Collection <__NSSetM: 0x7fb2e9dcab40> was mutated while being enumerated.
java[1450:32253] (
	0   CoreFoundation                      0x00007fff973e84f2 __exceptionPreprocess + 178
	1   libobjc.A.dylib                     0x00007fff8c5f5f7e objc_exception_throw + 48
	2   CoreFoundation                      0x00007fff9744f15c __NSFastEnumerationMutationHandler + 300
	3   CoreFoundation                      0x00007fff97382404 __NSSetEnumerate + 740
	4   CoreFoundation                      0x00007fff9738208a -[NSSet objectsWithOptions:passingTest:] + 234
	5   AppKit                              0x00007fff97e0dd61 -[NSView(NSInternal) _uninstallRemovedTrackingAreas] + 391
	6   AppKit                              0x00007fff97eb3282 -[NSView(NSInternal) _updateTrackingAreas] + 902
	7   AppKit                              0x00007fff9855f9e1 ___NSWindowGetDisplayCycleObserver_block_invoke6376 + 1265
	8   AppKit                              0x00007fff981ce0c9 __37+[NSDisplayCycle currentDisplayCycle]_block_invoke23 + 292
	9   QuartzCore                          0x00007fff87e20f71 _ZN2CA11Transaction19run_commit_handlersE18CATransactionPhase + 85
	10  QuartzCore                          0x00007fff87e20d1b _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 2447
	11  QuartzCore                          0x00007fff87e200ec _ZN2CA11Transaction6commitEv + 508
	12  QuartzCore                          0x00007fff87e2b977 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 71
	13  CoreFoundation                      0x00007fff9737d067 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
	14  CoreFoundation                      0x00007fff9737cfd7 __CFRunLoopDoObservers + 391
	15  CoreFoundation                      0x00007fff9735bef8 CFRunLoopRunSpecific + 328
	16  HIToolbox                           0x00007fff89479935 RunCurrentEventLoopInMode + 235
	17  HIToolbox                           0x00007fff8947976f ReceiveNextEventCommon + 432
	18  HIToolbox                           0x00007fff894795af _BlockUntilNextEventMatchingListInModeWithFilter + 71
	19  AppKit                              0x00007fff97d82df6 _DPSNextEvent + 1067
	20  AppKit                              0x00007fff97d82226 -[NSApplication _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 454
	21  libosxapp.dylib                     0x00000001212f63aa -[NSApplicationAWT nextEventMatchingMask:untilDate:inMode:dequeue:] + 124
	22  AppKit                              0x00007fff97d76d80 -[NSApplication run] + 682
	23  libosxapp.dylib                     0x00000001212f614d +[NSApplicationAWT runAWTLoopWithApp:] + 156
	24  libawt_lwawt.dylib                  0x00000001221f655b -[AWTStarter starter:] + 905
	25  Foundation                          0x00007fff91557fde __NSThreadPerformPerform + 279
	26  CoreFoundation                      0x00007fff9737d881 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
	27  CoreFoundation                      0x00007fff9735cfbc __CFRunLoopDoSources0 + 556
	28  CoreFoundation                      0x00007fff9735c4df __CFRunLoopRun + 927
	29  CoreFoundation                      0x00007fff9735bed8 CFRunLoopRunSpecific + 296
	30  java                                0x0000000102130463 CreateExecutionEnvironment + 871
	31  java                                0x000000010212c1ac JLI_Launch + 1952
	32  java                                0x00000001021324c0 main + 101
	33  java                                0x000000010212ba04 start + 52
	34  ???                                 0x0000000000000009 0x0 + 9
)


while executing the following function (via LibGDX):

/** Kindly stolen from http://lwjgl.org/wiki/index.php?title=LWJGL_Basics_5_(Fullscreen), not perfect but will do. */
@Override
public boolean setWindowedMode (int width, int height) {
  if (getWidth() == width && getHeight() == height && !Display.isFullscreen()) {
    return true;
  }

  try {
    org.lwjgl.opengl.DisplayMode targetDisplayMode = null;
    boolean fullscreen = false;

    if (fullscreen) {
      org.lwjgl.opengl.DisplayMode[] modes = Display.getAvailableDisplayModes();
      int freq = 0;

      for (int i = 0; i < modes.length; i++) {
        org.lwjgl.opengl.DisplayMode current = modes[i];

        if ((current.getWidth() == width) && (current.getHeight() == height)) {
          if ((targetDisplayMode == null) || (current.getFrequency() >= freq)) {
            if ((targetDisplayMode == null) || (current.getBitsPerPixel() > targetDisplayMode.getBitsPerPixel())) {
              targetDisplayMode = current;
              freq = targetDisplayMode.getFrequency();
            }
          }

          // if we've found a match for bpp and frequence against the
          // original display mode then it's probably best to go for this one
          // since it's most likely compatible with the monitor
          if ((current.getBitsPerPixel() == Display.getDesktopDisplayMode().getBitsPerPixel())
            && (current.getFrequency() == Display.getDesktopDisplayMode().getFrequency())) {
            targetDisplayMode = current;
            break;
          }
        }
      }
    } else {
      targetDisplayMode = new org.lwjgl.opengl.DisplayMode(width, height);
    }

    if (targetDisplayMode == null) {
      return false;
    }

    boolean resizable = !fullscreen && config.resizable;

    Display.setDisplayMode(targetDisplayMode);
    Display.setFullscreen(fullscreen);
    // Workaround for bug in LWJGL whereby resizable state is lost on DisplayMode change
    if (resizable == Display.isResizable()) {
      Display.setResizable(!resizable);
    }
    Display.setResizable(resizable);

    float scaleFactor = Display.getPixelScaleFactor();
    config.width = (int)(targetDisplayMode.getWidth() * scaleFactor);
    config.height = (int)(targetDisplayMode.getHeight() * scaleFactor);
    if (Gdx.gl != null) Gdx.gl.glViewport(0, 0, config.width, config.height);
    resize = true;
    return true;
  } catch (LWJGLException e) {
    return false;
  }
}


with the display initially created as following:

// Pixel format

int bpp = 24;
int alpha = 8;
int depth = 16;
int stencil = 0;
int samples = 0;

// OpenGL context:

int majorVersion = 3;
int minorVersion = 2;
boolean forwardCompatible = false;
boolean profileCore = true;

// Display Creation:

System.setProperty("org.lwjgl.opengl.Display.enableHighDPI", true));
ContextAttribs context = new ContextAttribs(majorVersion, minorVersion).withForwardCompatible(forwardCompatible).withProfileCore(profileCore);
Display.create(new PixelFormat(bpp, alpha, depth, stencil, samples), context);