Using Xcode OpenGL ES Frame Capture



Using Xcode OpenGL ES Frame Capture

November 20, 2012

Xcode OpenGL ES Frame Capture

Having used Microsoft Visual Studio a while ago, I think that the real difference with Xcode is that Xcode comes with a full suite of performance tools for free. Instruments is the most obvious one, but since version 4.5, Xcode includes a facility for capturing and analysing OpenGL ES frames. This tool, called OpenGL ES Frame Capture, is really simple and powerful: you can log all the OpenGL calls for a frame, inspects the content of OpenGL buffers, sees your OpenGL ES 2.0 shaders (even the “hidden” ones used by GLKBaseEffect). This is a quick review about how to use it in your app.

To follow this review and test a sample code, you can use one of the excellent Ray Wenderlich OpenGL/GLKit tutorials like OpenGL ES 2.0 for iPhone Tutorial or How To Create A Simple 2D iPhone Game with OpenGL ES 2.0 and GLKit.

Disclaimer: I’m a completely OpenGL rookie so I might employ not the right terminology in the following post. That’s said, let’s go!

1. How to setup OpenGL ES Frame Capture

There is a short Apple documentation about OpenGL ES Frame Capture. To capture OpenGL frames, you’ll need to use, at least, Xcode 4.5. The capture can only be done on a real device, running at minimum iOS 5, and connected to your Mac.

If you’re already including GLKit or OpenGL framework in your code, your project is already set up for OpenGL frames capturing. Anyway, you can check it by going to Product > Manage Schemes…, double-click you app scheme, click on Edit….

Enable capture

Tap on the Run scheme, then Options tab and check that ’OpenGL ES Frame Capture’ is set to Automatically Enabled or Enabled.

2. Capturing a Frame

You can capture a frame while you’re debugging your app. Launch the app in Debug mode (Product > Run or ⌘R). Once the app is launched, display the Debug Navigator (View > Navigators > Show Debug Navigator), and click on the FPS section of the Debug Navigator.

Show Debug Navigator

You can watch the FPS updated while playing with your app and test different use cases. Your mission, if you accept it, is to maintain a good 60 FPS. On my app sample, I’m currently running at 36 FPS so I will need to find where the performance bottleneck is.

Debug Navigator zoomed36 fps is not good, I would like to have 60 fps!

In the editor, you can see the time spent in the CPU and the GPU. If you want to achieve 60 FPS, you basically have 16 ms to update and render each frame. In my app, I’m spending 27 ms in the CPU and only 5 ms in the GPU.

CPU vs GPU

Given this number, I can already see that my problems are not on the GPU side, but maybe simply in my code. Let’s capture a trace to have a better view of what’s happening at each frame rendering. Just above the Debug console, tap on the Camera icon to capture an entire frame:

Capture Frame icon

After clicking on the Capture frame icon (the capture take a few secons), you will have access in the Debug Navigator to the OpenGL frames:

OpenGL frames overview

On the device, you can see that the captured frame is displayed and paused. In the Debug Navigator, if you expand the rendering icon , you will see all the OpenGL calls for the frame you’ve just captured. The Debug Navigator has a list of every draw call and state call associated with that frame (and your code call stack). The buffers associated with the frame are shown in the editor pane, and the state information is shown in the debug pane.

Show Debug Navigator

If you don’t see the OpenGL objects pane (the blue one), just click on the assistant icon, and select in the power bar, for instance, All GL Objects:

Assistant power bar

You can right click in the Buffer pane and select Show Draw Call Highlight to see a cute green triangle on the triangle drawn by the call:

Draw boxes

3. Inspecting OpenGL objects

In the assistant, you have access to the OpenGL objects like the Vertex buffers, the Index buffers, the binded (or not binded) texture, the shaders programs:

Objects panes

Click on the Index buffer will give you acces to the content of the buffer:

Index buffer

Click on the Programs will show you the corresponding shaders source code:

Shaders

It’s a super simple and convenient way to get the source code of the shaders ”hidden” by GLKBaseEffect!

4. Improving performances

Just watching at the OpenGL capture frame, one can see that there is a huge obvious performance improvement to be done. In my current app, I draw 200 planes sprites with their shadow. Each plane has it own texture so the pseudo code for this captured OpenGL frame is:

glBindTexture( texture-plane-type-0) // texture for the plane of type 0
glDrawArrays(GL_TRIANGLE_FAN, 0, 4) // draw 2 triangles (= 4 vertices in fan mode) for the sprite 

glBindTexture( texture-plane-type-6)
glDrawArrays(GL_TRIANGLE_FAN, 0, 4) 
…
…
…
…
glBindTexture( texture-plane-type-2)
glDrawArrays(GL_TRIANGLE_FAN, 0, 4) 

In the captured frame, there is practicality one render call for each sprite, resulting for more than 6000 OpenGL calls per frame! A very first optimisation is to have as few OpenGL calls as possible. In this case, instead of binding and rendering each planes one by one, I can use a Texture atlas and sprite batching to just bind one texture and only one draw call for all the planes. The resulted pseudo code will be:

glBindTexture( texture-atlas-for-planes) // texture for the plane of type 0
glDrawElements(GL_TRIANGLE_FAN, 0, 200 * 3 * 2) // draw 200 * 6 vertices for all sprites 

After having modified the code and recaptured the frame, one can see that all the planes are rendered in only one call (the green boxes show the triangle rendered by the selected OpenGL code):

Show Debug Navigator

The app is now at a good 60 FPS ! Xcode gives you also some advices: in that case, there is still room to add more effect and quality:

Improvement

5. Saving and sharing captured frames

One final thing: you can export and save your captured OpenGL frame. You can even share it with someones that don’t have your source code, if you want an OpenGL expert to analyse your calls.

Doing this is a bit awkward, I’ve not found a better way to do this, but it works. Select an OpenGL call in the Debug Navigator, then right click on the Xcode title bar where you can see the frame capture file name (*.gputrace):

Saving frame

You can see where Xcode temporally store the .gputrace file; you can then save this file in your Documents. If you want to reopen or share this file with someone, just connect a device on your Mac, double-click on the gputrace file and you will see this dialog box:

Importing

Click on Replay trace and Xcode will launch in a self-contained mode with just this file. Very convenient!




How to Use Xcode Frame Capture Debug Option

One of the newest features in Xcode is the frame capture debug option for OpenGL ES. I used it a lot recently trying to figure out what Unity was doing rendering-wise on iOS, and I was thinking that other developers might not know about this and find it useful.

The only problem is that it seems to use a lot of memory, so it will only work on small Unity scenes (it crashes on bigger ones). You may have to create a new small test scene to use it. (I did not try it on an iPhone 4s or 5, I think they should have enough memory for bigger scenes.)

Once you run your application on the device, in the debug area there is a camera icon that you can use to capture a frame.

For example, I had a test scene running on the iPod touch:

(You can click on the following images to make them bigger)

Doing a frame capture gave the following results in Xcode:

On the left side you get all the OpenGL calls, the middle view shows the content of the currently set render buffers of the current OpenGL call selected. The other views allow you to get more details about all loaded OpenGL objects and the current OpenGL context.

The glDrawElements(...) calls on the left side are when a mesh is rendered on the current bound buffers. For example the following image shows what happens when we select the first mesh rendered: 

On the farther right view, you can see the currently bound OpenGL objects for this call. For example we can see that a call to glUseProgram(16) happened before the glDrawElements, that's why we have program 16 as a currently bound object. 

The bottom right view gives more details about objects. Right now the view is set to show all OpenGL objects, and we can see details about program 16.

On the top right view, you can double-click on the objects to get even more details about them. For example double-clicking on the texture object allows you to see all the mipmap levels of the texture and some info about it:

Double-clicking on the program allows you to see the vertex and fragment shader GLSL code (I guess an advantage of runtime compilation :)) 

Finally the bottom left view shows the current OpenGL context:

Also for those not familiar with Xcode, to navigate back you need to use the navigation bar at the top of each view (Took me a while to figure that out :)):

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: OpenGLESOpenGL for Embedded Systems)是一种专门为嵌入式系统设计的二维和三维绘图API。想要下载OpenGLES,可以按照以下步骤进行操作。 首先,打开任何一个主流网页浏览器,例如谷歌浏览器(Google Chrome),火狐浏览器(Mozilla Firefox)等。 接下来,在浏览器的搜索栏中输入“OpenGLES下载”或者直接搜索“OpenGLES官方网站”。点击搜索按钮或者按下回车键进行搜索。 然后,在搜索结果中,找到OpenGLES的官方网站。通常,官方网站是最可靠和安全的来源。点击链接进入官方网站。 一旦进入官方网站,往往会有下载页面或下载链接。浏览页面,寻找与您操作系统和设备兼容的版本。例如,如果您使用的是Android手机,那么您需要选择适用于Android的OpenGLES版本。 找到合适的版本后,点击下载按钮或链接。通常,会弹出一个保存文件的窗口。选择一个您常用的文件夹或位置,保存下载的文件。 一旦下载完成,您可以在文件夹中找到下载的文件。根据您的需求和操作系统,您可能需要进行一些额外的设置或安装。按照下载文件的说明进行相应操作即可。 总之,要下载OpenGLES,首先需要在浏览器中搜索并进入OpenGLES的官方网站,然后选择适用于您的设备和操作系统的版本,最后按照下载文件的说明进行安装和设置。 ### 回答2: 在OpenGLES的下载方面,首先需要了解OpenGLES是什么。OpenGLES(Open Graphics Library for Embedded Systems)是一套用于嵌入式系统的图形应用程序接口,主要用于在移动设备、游戏控制台和嵌入式系统上进行图形渲染和加速。 要下载OpenGLES,首先需要到对应的官方网站或者相关的开发者社区,例如OpenGL官方网站、Github等,进行下载。在网站上通常会提供最新版本的OpenGLES的软件包,你可以根据你的开发需求选择相应的版本进行下载。 下载OpenGLES之前,你需要确定你的目标平台和操作系统。因为OpenGLES支持的平台众多,例如Android、iOS、Windows、Linux等,每个平台都有对应的编译器和开发工具链,需要根据自己的开发环境进行选择。 在下载OpenGLES之后,你可以根据对应的安装包解压缩或者进行安装。解压缩后,你会发现里面包含了相关的开发库、头文件、示例代码等。根据你使用的开发环境,将这些文件添加到你的项目中,并进行相应的配置。例如,如果你是在Android平台上开发,你可以将OpenGLES的库文件添加到Android工程中,并在代码中引入相关的头文件。 此外,在下载OpenGLES之后,你还需要阅读完整的文档,学习如何正确地使用OpenGLES进行图形渲染和加速。OpenGLES提供了丰富的功能和接口,比如顶点着色器、片元着色器、纹理贴图等,你可以根据需求学习和应用这些功能。 总而言之,下载OpenGLES需要到官方网站或者开发者社区下载对应版本的软件包,并根据自己的开发环境进行配置和安装。在使用OpenGLES之前,建议阅读相关的文档和教程,加深对OpenGLES的理解和应用。 ### 回答3: OpenGLESOpenGL ES)是一种用于嵌入式设备的图形渲染应用程序编程接口(API)。要下载OpenGLES,首先需要找到适用于您的操作系统的OpenGLES SDK,并从官方网站或其他可信来源下载。 对于Android设备,Android提供了OpenGLES SDK作为Android SDK的一部分。您可以从Android开发者网站下载适用于您的操作系统版本的Android SDK。安装Android SDK后,在SDK管理器中选择并安装OpenGLES SDK。 对于iOS设备,OpenGLES已经集成到iOS开发环境中。您只需下载并安装最新版本的Xcode开发工具包,即可获得OpenGLES SDK。 另外,对于其他嵌入式设备和操作系统,您可以在官方网站或其他相关开发者社区中寻找OpenGLES SDK的适用版本,并按照其提供的指南进行下载和安装。 下载和安装OpenGLES SDK后,您就可以开始使用OpenGLES进行图形渲染和开发应用程序了。根据您的需求,您可能还需要了解OpenGLES的基本语法、渲染管线和相关的图形编程概念。有许多在线文档和教程可供学习,您可以在网络上搜索并参考这些资源。 总之,要下载OpenGLES,您需要找到适用于您的设备和操作系统的OpenGLES SDK,并按照其提供的指南进行下载和安装。然后,您可以开始学习并使用OpenGLES进行图形渲染和应用程序开发。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值