MetalGL 0.10.0 Sample Projects

Copyright (c) 2014-2015 The Brenwill Workshop Ltd. All rights reserved.

Table of Contents

Introduction

The Xcode projects in this folder are a set of sample applications that demonstrate the situations when implementing your OpenGL ES rendering in Metal via MetalGL can improve the rendering performance of your OpenGL ES application.

To review and run all of the available sample apps, open the SampleProjects.workspace Xcode workspace in Xcode.

Each sample app can be configured to render OpenGL calls using the native OpenGL ES engine, or render the same OpenGL calls using Metal, by redirecting the OpenGL calls to MetalGL.

Comparing MetalGL against OpenGL ES

In each sample app, the selection of whether to render using OpenGL ES or Metal is handled by the value of the MGL_SUPPORT_OPENGL_ON_METAL parameter, as set in the Preprocessor Macros (aka GCC_PREPROCESSOR_DEFINITIONS) Xcode build setting. Setting the value of this parameter to 0 will cause rendering to be performed by the native OpenGL ES engine. Setting the value of this parameter to 1 will cause rendering to be performed by Metal, by redirecting all OpenGL calls to MetalGL.

To change whether a sample app uses Metal or native OpenGL ES to render:

  1. Open the SampleProjects.xcworkspace workspace in Xcode.

  2. In the Project Navigator panel, select a sample app project.

  3. Select either the iOS or OSX target of the sample app project.

  4. In the Build Editor pane, select the Build Settings tab.

  5. Locate the Preprocessor Macros (aka GCC_PREPROCESSOR_DEFINITIONS) build setting for the target.

  6. Change the value of the MGL_SUPPORT_OPENGL_ON_METAL parameter to 0 to render using native OpenGL ES, or 1 to render using Metal:

    MGL_SUPPORT_OPENGL_ON_METAL=0
              -- or --
    MGL_SUPPORT_OPENGL_ON_METAL=1
  7. If you are configuring to test native OpenGL ES under OS X, you must provide a native OpenGL ES implementation. You can do this by following the instructions in the Adding Support for Native OpenGL ES 2.0 in OS X section below, for each sample project.

  8. Build and run the sample app.

The sample app displays an on-screen indication that rendering is being performed by either MetalGL or native OpenGL ES, and also displays the average frames-per-second (FPS) in the lower-left corner of the screen.

For correct evaluation of app performance, ensure that the Xcode build Scheme is set to use Release mode. This is the default mode for each sample app. If you build using Debug mode, the sample app will display a [DEBUG] indicator on the screen, to indicate that performance measurements are not accurate.

On OS X, comparing OpenGL ES to MetalGL is a skewed comparison. Since OS X does not natively support OpenGL ES, most "native" OpenGL ES implementations on OS X (including the one described in the section below), must convert OpenGL ES calls and state to desktop OpenGL calls and state. Since there is always some level of overhead in managing that conversion, one could say MetalGL has a bit of an unfair advantage in these comparisons (relative to, say, comparing against a true native desktop OpenGL implementation).

However, performing the comparison on OS X anyway does highlight the important point that MetalGL enables you to seamlessly port an OpenGL ES application that you might have written for iOS to OS X without having to convert your application to desktop OpenGL. You can leave your application implemented in OpenGL ES (including the shaders) and gain the strength of Metal to power your application on OS X.

Adding Support for Native OpenGL ES 2.0 in OS X

MetalGL supports OpenGL ES under OS X, and all of the sample applications will run correctly on OS X when Metal is available (El Capitan and above).

However, when Metal is not available under OS X, in order to run any of the sample applications using native OpenGL ES under OS X, a "native" OpenGL ES implementation must be provided. This is because OS X supports desktop OpenGL by default, not OpenGL ES.

You can use any "native" OpenGL ES implementation for OS X you prefer. If you do not already have a preference, you can download a free implementation here. This implementation contains both OpenGL ES 2.0 and EGL libraries, and converts OpenGL ES 2.0 calls to the desktop OpenGL calls available on OS X.

To configure the sample apps for testing with this "native" implementation of OpenGL ES, perform the following steps (or follow similar steps if you already have a preferred implementation of OpenGL ES for OS X).

Remember that you do not need to perform these steps in order to run the sample apps under OS X when Metal is available.

Unzip the downloaded file, and move the libGLESv2.dylib and libEGL.dylib files to the SampleProjects/Common/PVRShell/OSX/OGLES2 folder in the MetalGL distribution.

For each sample app that you want to test using "native" OpenGL ES under OS X, follow these steps:

  1. Open the SampleProjects.xcworkspace workspace in Xcode.

  2. In the Project Navigator panel, select a sample app project.

  3. In the Project Navigator panel, remove the references to the gl.m and egl.m files from the Support/PVRShell/OSX group of the sample app project.

  4. Drag the libGLESv2.dylib and libEGL.dylib files (which you added above) from the SampleProjects/Common/PVRShell/OSX/OGLES2 folder to the Frameworks/OSX group in the Xcode Project Navigator panel. In the dialog that opens, add the files to the OSX target.

  5. Select the sample app project in the Project Navigator panel, select the OSX target, and select the Build Phases tab. Drag the libGLESv2.dylib and libEGL.dylib files from the Frameworks/OSX group in the Xcode Project Navigator panel to the Copy Files list in the Build Phases tab.

    Hint: If you find it difficult to select both files in the Frameworks/OSX group without switching away from the Build Phases tab of the project target, use the Command key on your keyboard when selecting each of the files, or try dragging the files one by one from the Frameworks/OSX group to the Copy Files list in the Build Phases tab.

  6. Follow the instructions in the section above to configure the sample app to use Metal instead of OpenGL ES.

DrawLoad Sample Application

The DrawLoadDemo sample app displays a large collection of colored balls actively bouncing around the scene. Each ball is rendered using one OpenGL draw call, meaning the number of draw calls made during each frame is about the same as the number of balls displayed. In addition, since each ball is a different color, and the balls are moving around, several OpenGL state calls are made prior to each draw call. The result is a very large number of OpenGL calls on each frame.

In the bottom left corner of the screen, the demo displays the number of draw calls being performed each frame, the number of triangles being rendered each frame (both per draw call and total per frame), and the average number of frames-per-second being rendered.

This sample app demonstrates the conditions under which Metal (via MetalGL) performs better than OpenGL, and the conditions under which both Metal and OpenGL perform about the same.

You can change the number of balls being rendered by swiping up or down on the screen under iOS, or by using the cursor keys under OS X. To see the performance improvement provided by Metal (via MetalGL), increase the number of balls being rendered until you see the frame rate drop below 60 fps for each of OpenGL and MetalGL (see the section above for how to switch between OpenGL and MetalGL).

Another aspect that affects performance for both OpenGL and Metal is the complexity of the meshes (number of vertices and faces) being rendered. To see the effect of varying the mesh complexity of each ball, modify the value of the MGL_DEMO_POLY_SIZE parameter in the Preprocessor Macros (aka GCC_PREPROCESSOR_DEFINITIONS) build setting of the sample app target (the DrawLoadDemo-iOS or DrawLoadDemo-OSX target) within Xcode. Valid values for this parameter are 80, 320 and 1280, corresponding to meshes with 80, 320, and 1280 triangle faces per ball, respectively.

Because Metal is much more efficient than OpenGL when performing graphics engine calls, the performance improvement provided by Metal is most apparent when a large number of balls are being rendered, and the mesh complexity of each ball is lower. For instance, you should notice that, in this app, MetalGL is about twice as fast as OpenGL for the ball mesh with 80 faces, and a large number of balls.

As you increase the complexity of each ball mesh, the GPU must spend more and more time simply rendering vertices and fragments, causing the GPU to eventually become the bottleneck. In applications where raw rendering in the GPU is the bottleneck, the performance of OpenGL and Metal will be about the same. For instance, for the ball mesh with 320 faces, you should notice that Metal is still much faster than OpenGL, but the improvement is not quite as strong as when using the less-complex mesh with 80 faces. Similarly, for the ball mesh with 1280 faces, you should notice that Metal performs about the same as OpenGL.

Understanding this sample app will help you optimize your own apps, to benefit the most in the transition from OpenGL to Metal. If your app is limited by the GPU (the raw rendering of vertices and fragments), or by CPU effort spent away from the graphics engine (for instance, physics calculations, or other app control), you may not see much improvement from Metal. Once you have optimized those components, so that calls to the OpenGL graphics engine become the bottleneck, the improved performance of Metal will shine through.

You can pause or resume the movement in the scene by tapping on the screen under iOS, or by pressing either the 1 or 2 key under OS X.

Particles Sample Application

The ParticlesDemo sample app displays a large collection of point particles. The particles are active and move around the scene, but all of the particles are rendered using a single OpenGL draw call.

In the bottom left corner of the screen, the demo displays the number of particles and the average number of frames-per-second being rendered.

You can change the number of particles being rendered by swiping up or down on the screen under iOS, or by using the cursor keys under OS X.

Even though the scene is very active, because point-particle rendering is performed with a very small number of draw calls, this sample app demonstrates a situation where Metal improves performance a relatively small amount over native OpenGL ES (typically a 10% - 20% improvement on modern hardware).

You can pause or resume the movement in the scene by tapping on the screen under iOS, or by pressing either the 1 or 2 key under OS X.


The MetalGL sample apps include components of the PowerVRTM SDK from Imagination Technologies Limited. The PowerVRTM SDK is freely available through an open-source license, with attribution required.