OpenGLContext crashes on iOS, possible bug?

I’m trying to attach OpenGLContext to a Component on iOS. The same code works on Desktop (macOS, Win, I didn’t test it on Android yet).
I can’t post the whole code because it’s a big application, it looks like the FrameBuffers are not properly initialized, an error is displayed on line 279 of juce_OpenGL_ios.h

jassert (glCheckFramebufferStatus (GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
***** GL_INVALID_VALUE at /JUCE/modules/juce_opengl/native/juce_OpenGL_ios.h : 279
JUCE Assertion failure in juce_opengl.cpp:221

At this point the OpenGLContext should be active, I printed it out :
**Version:OpenGL ES 3.0 APPLE-18.0.31, Vendor:Apple Inc., Renderer:Apple Software Renderer**
The OpenGL Context is initialized as follow:

addToDesktop(0); //This is not necessary on Desktop openGLContext.setOpenGLVersionRequired(juce::OpenGLContext::openGL3_2);
openGLContext.setComponentPaintingEnabled(true);
openGLContext.setMultisamplingEnabled(true);
openGLContext.attachTo(*this);
openGLContext.makeActive();

It is also not possible to use a juce::OpenGLImageType() in an Image, the following code:
img = juce::Image(juce::Image::ARGB, width, height, true, juce::OpenGLImageType());
crashes in the same place (on iOS, on Desktop works). The OpenGLContext was initialized in the same way.
@ed95 is this a bug or I forgot something?
Regards.

I upgraded to Juce 6.0.3, the error persists, on iOS the app crashes in the same place. OpenGLImageType crashes too (same place).
@ed95 @t0m as I mentioned earlier, I think this is a bug.
Regards.

It’s hard to say without seeing any more of your code. Are you able to run the JUCE OpenGL demo apps on iOS without crashes? In the DemoRunner you can select the OpenGL Renderer from the “Renderer” drop-down in the settings tab and try to open any of the GUI/OpenGL demos. I don’t have access to an iDevice at the moment but it’s working fine for me in the simulator.

@ed95 thanks for your answer. Demo Runner’s OpenGL samples will work if you are using OpenGLES 2. If you force OpenGL 3 it crashes in the same place or you have distorted output.
I’ve added the following lines to OpenGLDemo2D’s constructor:

OpenGLDemo2D()
{
setOpaque (true);

    if (auto* peer = getPeer())
        peer->setCurrentRenderingEngine (0);
  openGLContext.setOpenGLVersionRequired(juce::OpenGLContext::openGL3_2);
  openGLContext.setMultisamplingEnabled(true);
  openGLContext.setComponentPaintingEnabled(true);
  openGLContext.attachTo (*getTopLevelComponent()); ...

As you can see, I am forcing the use of OpenGL 3 ES in the constructor. This will cause the demo runner to crash or it produces the following output:


The same thing happens in the other examples, it crashes or the output is distorted if you use OpenGL3 ES.
I’m working on Xcode 12.0.1, and I have targeted iOS 12.
Another point: the CPU Usage in the examples OpenGLAppDemo and OpenGLDemo is always between 90 and 100% (using OpenGL 2 ES).
Regards.

The glitchy output should be fixed with this commit:

When using OpenGL 3 with multisampling enabled, we weren’t scaling the logical to physical pixels correctly before calling glBlitFramebuffer causing only part of the screen to be drawn.

I can’t reproduce the crashes though. Could it be that you are targeting a device which doesn’t support OpenGL 3?

@ed95 thanks for your reply. Yes, some problems are solved with your commit. OpenGLES3 still sometimes crashes:

  • It crashes when you paint a large area, e.g. 1000 x 6000, then crashes at the following point:

juce_WaitableEvent.cpp
z. 39: condition.wait (lock, [this] { return triggered == true; });

juce::MessageManager::lock::BlockingMessage::messageCallback() at /JUCE_6_0_4/JUCE/modules/juce_events/messages/juce_MessageManager.cpp:288

***** GL_INVALID_VALUE at /JUCE/JUCE_6_0_4/JUCE/modules/juce_opengl/opengl/juce_OpenGLTexture.cpp : 102
JUCE Assertion failure in juce_opengl.cpp:216

  • It’s still not possible to rewrite / reassign / deallocate an Image using OpenGLNativeImageType f.e. if you declare an Image as follow:

img = juce::Image(juce::Image::ARGB,
width, height, true,
juce::OpenGLImageType());

and you want to rewrite it in another method, this will result in a crash in the following place:

***** GL_INVALID_FRAMEBUFFER_OPERATION at /Users/luisvaldivia/JUCE/JUCE_6_0_4/JUCE/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp : 1282
JUCE Assertion failure in juce_opengl.cpp:216

  • The CPU usage is very high, especially when animations are running. You can check this in the Demo Runner. The CPU is always between 90 and 100% by running OpenGLAppDemo or OpenGLDemo through Demo Runner. No matter whether you use OpenGL2ES or OpenGL3ES. These examples run with a CPU usage of 7% on desktop.
    The errors described above work fine in desktop. If necessary I can send you 2 minimal examples.
    Regards.

@ed95

  • Changing the OpenGLDemo2D constructor as follows will cause a similar crash:

OpenGLDemo2D()
{
setOpaque (true);

    if (auto* peer = getPeer())
        peer->setCurrentRenderingEngine (0);
  openGLContext.setOpenGLVersionRequired(juce::OpenGLContext::openGL3_2);
  openGLContext.setMultisamplingEnabled(true);
  openGLContext.setComponentPaintingEnabled(true);
    openGLContext.attachTo (*getTopLevelComponent());

    addAndMakeVisible (statusLabel);
    statusLabel.setJustificationType (Justification::topLeft);
    statusLabel.setFont (Font (14.0f));

    auto presets = getPresets();

    for (int i = 0; i < presets.size(); ++i)
        presetBox.addItem (presets[i].name, i + 1);

    addAndMakeVisible (presetLabel);
    presetLabel.attachToComponent (&presetBox, true);

    addAndMakeVisible (presetBox);
    presetBox.onChange = [this] { selectPreset (presetBox.getSelectedItemIndex()); };

    fragmentEditorComp.setOpaque (false);
    fragmentDocument.addListener (this);
    addAndMakeVisible (fragmentEditorComp);

    presetBox.setSelectedItemIndex (0);

    setSize (500, 3500);
}
  • Attached is a minimal example of the crash with OpenGLImageType. There are 2 errors here: No image is displayed; and when you rotate the emulator (tested with iPadPro emulator) should the crash be triggered
    GLImage_Crash.zip (4.1 KB)
    This is just a simple example in order to show you the crash. All this works fine on Desktop.
  • It would be nice if you could improve the performance, as I said before the CPU usage is almost always between 90 and 100%, the performance with Core Graphics is no better (it’s almost similar). With this level of performance it’s almost impossible to use any animation.
    Regards.