See also

Note: The GPU Debugger has been removed from Android Studio as of version
2.3. An open-source, standalone version of the tool is available on
GitHub.

After you capture a GPU trace, you can then analyze it in the GPU Debugger. It
provides interactive visual tools so you can examine different aspects of app
graphics rendering with OpenGL ES 2.0 or 3.1. At the same time, it lets you view the call
hierarchy, dynamically change function arguments, view the contents of memory,
and more. You can deep dive into each frame, both graphically and
programmatically.

For more information
about OpenGL ES, see khronos.org.
It has a quick reference card that summarizes the commands in a
few short pages and can be useful while you're using the GPU Debugger.

In the GPU Commands pane, expand the call hierarchy within
the frame you selected and examine the calls of interest.

Select a tab to explore the graphical objects, state, and memory values
associated with the frame.

Figure 1. Main areas of the GPU Debugger.

Analyzing your app starts with choosing a rendering context. A context
is required to execute OpenGL ES commands. It gathers the states needed for
rendering an image and has information about relevant buffers, shaders,
textures, and so on. Many game apps have just one context. More advanced apps may use more
than a single context.

If your app has more than one context, it's easier to use the tool if you choose
one context instead of all of them. When you select one context, the calls are
grouped by frame in the GPU Commands pane. If you select all
contexts, the calls are instead grouped by context.

Frame thumbnails appear beneath the context menu in a timeline. They correspond
to the list of frames in the GPU Commands pane. Both areas
always show the same selected frame. When you select a frame in the timeline,
that same frame is selected in GPU Commands pane; when you
select a frame in the GPU Commands pane, the same frame is
selected in the timeline.

The GPU Commands pane displays OpenGL ES calls for each frame.
Expand the tree to examine the calls.

A frame ends when the app calls the eglSwapBuffers() function,
which is used by double-buffering apps. If your app doesn't support
double-buffering, however, you might end up with a single frame after a trace.
The frame thumbnails show the onscreen display after the buffers are swapped.

After you select a frame, you can explore it further using the various tabs:

Organize the GPU Debugger tabs

You can rearrange the tabs to best suit your development process. After you
rearrange the panes, the GPU Debugger remembers the configuration whenever you
open a trace file afterward.

Here are some ways to rearrange the tabs:

To reorder the tab group, move the tabs back and forth.

To move a tab to a standalone window, drag the tab to a different location
on the screen. You can drag other tabs into the same standalone window.

To dock a standalone window, drag it to the GPU Debugger tab bar.

To combine tabs together into one pane, drag a tab outside of the tab bar
and move it onto another pane.

To move a tab to a pane on the left or right side, drag the tab to the side
of another pane until you see a purple highlighted area, and then release it. To
move a tab to a bottom pane, drag the tab to the bottom of a pane until you see
the purple highlighted area, and then release it. The GPU Debugger can have a
maximum of three docked panes side-by-side, and one on the bottom, at a time.

To hide a tab, click Hide. To make it reappear, click Restore View
on the far right and above the row of tabs.

Figure 2 shows one possible configuration, where the graphical windows are in
the middle pane, and the state and memory details are in the right pane.

Figure 2. Reorganized GPU Monitor tabs.

Examine OpenGL ES calls in the GPU Commands pane

When you display one context, the GPU Commands pane displays
OpenGL ES calls grouped by frame. It also groups draw commands under a
Draw node. You can create additional groupings by adding debug
markers to your code, as described in the following section.

When you select a call or frame thumbnail, the GPU Debugger updates all tabs to
the same state: after the call was executed. For example, if you click a memory
address or pointer, the values appear in the Memory pane.

You can perform the following operations in the GPU Commands
pane:

To expand or collapse an item in the call hierarchy, click
or double-click the item.

To search for a command, type a string in the search field
at the top of the pane, and then press Return. If you want to
use a regular expression search pattern, select Regex. To find
the next occurrence, select the search field and press Return
again.

To change argument values, right-click a function and choose
Edit. In the Edit dialog, change one or more
values in the fields, and then click OK.
Arguments that are in
the highlight color and not underlined are editable, except for memory
locations.

If you click an argument that refers to a state parameter, such as a texture
ID, the GPU State pane opens and shows
you more information. If you click a memory address or pointer, the
Memory pane opens and shows you
that location in memory.

To magnify a call thumbnail, hover your cursor over it. The thumbnail appears to the
left of a call.

To copy values from the display, select the items to copy and then press
Control+C or Command+C. You can then paste the information into a text file.

Define debug markers

Depending on your app, the GPU Command pane can contain a very
long list of OpenGL ES calls within one frame. For better navigation and
readability, you can define debug markers that group calls together under a
heading in the tree.

For example, figure 3 shows several debug markers:

Setup and Render World are debug markers
at the top level of the Frame 225 call hierarchy.

Within Render World is another layer of debug marker
hierarchy: Scene Setup and RenderPass.

Considering that Frame 225 contains 1453 commands, you can see that the debug
markers are quite helpful.

Figure 3. Debug markers in the
GPU Commands pane.

As shown in the figure, the glPushGroupMarkerEXT() and
glPopGroupMarkerEXT()functions add and then remove the debug marker
string of Render World. For more information about adding debug
markers to your code, see EXT_debug_marker
on the khronos.org website.

The GPU Debugger automatically adds a Draw grouping if it's
completely within or outside of a user-defined debug marker group. However, if
part of it is both within and outside of a user-defined debug marker group, the
Draw grouping won't appear.

Examine the framebuffer

The Framebuffer pane shows the contents of the currently bound
default framebuffer. Depending on the item you select in the GPU
Commands pane, it can show onscreen or offscreen framebuffers.

When you select a command in the GPU Commands pane, the
Framebuffer pane displays the contents of the framebuffer after
that call finishes. If you select a Draw grouping or debug
marker, it displays the framebuffer after the last call in the group finishes.
However, if you select a Frame grouping, the
Framebuffer pane displays the framebuffer before the
eglSwapBuffers() function finishes — ahead of the buffer swap.

In essence, you can start by selecting the first call within a frame, and then
click each successive call to watch the framebuffer components draw one-by-one
until the end of the frame. These framebuffer displays, for both onscreen and
offscreen graphics, help you to locate the source of any rendering errors.

To examine a framebuffer in the Framebuffer pane, follow these
general steps:

In the GPU Commands pane, select a call, frame, or debug
marker. Or select a frame thumbnail in the timeline.

Select the Framebuffer tab.

The drawn framebuffer appears.

Use the toolbar buttons on the left of the Framebuffer pane
to examine the graphic.

Move your mouse over the framebuffer to view the x, y,
u, and v pixel coordinates, and the ARGB pixel color value, for the pixel
directly under the cursor. The values appear at the bottom of the pane.

The following table describes the operations you can perform with the toolbar
buttons.

Button

Description

Example

Color Buffer

Select this button to display the color buffer, as opposed to the depth
buffer.

Depth Buffer

Select this button to display the depth buffer, as opposed to the color
buffer. When the depth buffer is enabled, OpenGL ES performs a depth test for
each fragment, and it draws only those fragments that will be seen because
they're closer.

Shaded

Select this button to display shaded polygons.

Shaded + Wireframe

Select this button to display shaded polygons overlaid with the last draw
call represented as a wireframe. The wireframe is violet and highlights what was
drawn last. Zoom in to see the details.

Wireframe

Select the button to show a wireframe view of the framebuffer. It shows
the structure, vertices, number of triangles, and more. You can see through
objects and view hidden items to help with debugging them.

Zoom to Fit

Click the button to adjust the graphic to fit completely within the
Framebuffer pane. Right-clicking the image is another way to
Zoom to Fit.

Actual Size

Click the button to show the image at no scale, where one device pixel is
equivalent to one screen pixel.

Zoom In

Click the button to zoom in. You can also use your mouse wheel, or
two-finger swipes on a touchpad, to scroll in and out. You can drag the image
with your cursor.

Zoom Out

Click the button to zoom out. You can also use your mouse wheel, or
two-finger swipes on a touchpad, to scroll in and out.

Color Channels

Click the button and then select the color channels to render or deselect
color channels so they aren't rendered. The options are Red,
Green, Blue, and Alpha
(transparency).

Show Checkerboard

Select the button to enable the checkerboard background to indicate
transparency.

Examine textures

The Textures pane lets you view the textures created at or
before your position in the trace. Textures are images that you can apply to
your shape surfaces to provide detail. 2D textures are made of small blocks of
data, called texels.

Figure 6 shows texture images that are placed on sushi shapes.

Figure 6. Textures pane.

To examine textures in the Textures pane, follow these general
steps:

Select a call in the GPU Commands pane, or a frame
thumbnail in the timeline.

Select the Textures tab.

At the top of the Textures pane, select a texture from the
menu.

The texture appears under the menu.

The menu lists textures created at or
before your position in the trace; the textures aren't necessarily filled with data
yet, however.

Position the Level slider at the bottom of the
Textures pane to view different texture levels.

Each level
shows different texel densities of the same texture image. By looking
at the different densities, you can determine if you need to adjust an image so
the display at that density is optimal.

If a slider doesn't appear, then the
texture doesn't have multiple levels (it's not a mipmap).

Use the toolbar buttons on the left of the Textures pane to
examine the graphic.

Move your mouse over the texture to view the x, y, u, and
v coordinates, and the ARGB value, for the texel directly under the
cursor. The values appear at the bottom of the pane. The x and y values
represent screen space, and the u and v values represent texel space.

The following table describes the operations you can perform with the toolbar
buttons.

Button

Description

Example

Zoom to Fit

Click the button to adjust the graphic to fit completely within the
Textures pane. Right-clicking the image is another way to
Zoom to Fit.

Actual Size

Click the button to show the image at no scale, where one device pixel is
equivalent to one screen texel.

Zoom In

Click the button to zoom in. You can also use your mouse wheel, or
two-finger swipes on a touchpad, to scroll in and out. You can drag the image
with your cursor.

Zoom Out

Click the button to zoom out. You can also use your mouse wheel, or
two-finger swipes on a touchpad, to scroll in and out.

Color Channels

Click the button and then select the color channels to render or deselect
color channels so they aren't rendered. The options are Red,
Green, Blue, and Alpha
(transparency).

Show Checkerboard

Select the button to enable the checkerboard background to indicate
transparency.

Flip Vertically

By default, the Textures pane shows the texture the way
OpenGL ES sees it. When you click the button, the image flips across a
horizontal line. A selected button means that the image appears differently than
the default (it's flipped).

Accesses/
Modifications

Select this button to view a list of all calls that updated the texture
to this point. Select a call to view the texture after the call completes. The
selected frame thumbnail and the GPU Commands pane update
accordingly.

Examine image geometry

The Geometry pane renders an image in 3D. You can use your
mouse or touchpad to rotate the rendering, and zoom in and out. To display an
image in the Geometry pane, you must select a draw call in the
GPU Commands pane. For example, in figure 7, the
Geometry pane displays the image rendered after the selected
glDrawElements() call completes.

Figure 7. Geometry pane.

To examine an image in the Geometry pane, follow these general
steps:

Select a draw call in the GPU Commands pane.

Select the Geometry tab.

The image appears in the Geometry pane.

Use the toolbar buttons on the left of the Geometry pane to
examine the image.

Drag your cursor over the image to view all sides of the
image, including front and back. You can also use your mouse wheel, or
two-finger swipes on a touchpad, to zoom in and out. You can zoom in and look at
pixels to determine why something is rendering badly.

The following table describes the operations you can perform with the toolbar
buttons.

Button

Description

Example

Y-Up

Click the button to toggle between y axis up and z axis up. In OpenGL ES,
the default is the y axis pointing up, the x axis horizontal, and the z axis as
depth.

Triangle Winding

Toggle between counterclockwise and clockwise triangle winding to view
front- versus back-facing triangles. Dark green represents the back face, while
a lighter green represents the front face. If you set the button to the winding
convention that you use in your code, and the image appears dark, then you know
there's a problem with your geometry.

Shaded

Show the geometry rendered as shaded polygons.

Wireframe

Show the geometry rendered as a wireframe.

Point Cloud

Show the geometry rendered as vertex data points.

Original

Select this button to display smooth normals as specified in your code.
The button is unavailable if you haven't authored normals in your mesh.

Faceted

Select this button to see the lit geometry without using smooth normals.
It renders the geometry as if each polygon were flat instead of smoothed, using
computed face normals.

Backface Culling

disabled

enabled

Click this button to toggle backface culling, which determines whether
backward-facing polygons are rendered. Backface culling detects which polygons
aren't visible to the viewer, so they aren't rendered and improve rendering
efficiency. To troubleshoot problems with rendering backward-facing triangles,
first make sure the winding is set correctly. If the geometry appears correct,
then check backface culling.

Lit

Select this button to show lit shading.

Flat

Select this button to show flat shading. It displays a silhouette of the
mesh.

View the GPU state

OpenGL ES is basically a large state machine. Use the GPU State
pane to view the driver state at the point of the trace that's selected in the
GPU Commands pane. For example, you can see which OpenGL ES capabilities
are enabled. Figure 2, and figures 4 through 7, show examples of the GPU
State pane display.

For long lists of capabilities in a hierarchy, the GPU State
pane can display breadcrumb subtabs for easier navigation, as shown in figure 8.
Contexts is at the top of the hierarchy, and
24 is at the bottom.

Figure 8 illustrates how easy it is to view number-identified argument values.
Simply click the argument, such as Buffer: 24, in the
GPU Commands pane, and then view it in the GPU
State pane.

You can copy values from the display into a text file.

To examine the state in the GPU State pane, follow these
general steps:

In the GPU Commands pane, select a call, frame, or debug
marker. Or select a frame thumbnail from the timeline.

Select the GPU State tab.

The state values appear in the GPU State pane.

Navigate up and down the hierarchy as needed.

View values in memory

The Memory pane lets you view the values stored in memory for
the selected call. You can display the memory as a certain data type, and copy
values from the display into a text file. You can't edit memory values in the
GPU Debugger. Figures 9 and 10 show values as displayed in the
Memory pane.

Figure 9. read: line displayed in the
Memory pane.

Figure 10. Values: argument displayed
in the Memory pane.

In figure 10, the question marks (?) indicate areas of memory that weren't
captured, so the GPU Debugger doesn't know what it contains.

To examine memory values in the Memory pane, follow these
general steps:

In the GPU Commands pane, select a pointer argument, or a
read: or write: line, for a call.

Select the Memory tab.

The memory values appear in the Memory pane.

At the top menu of the Memory pane, select how you want to
view the memory values: Text or another data type.

Copy information from a pane

You can copy information from the GPU Commands, GPU
State, and Memory panes.

To copy values from the display, do the following:

Select the items to copy.

Press Control+C or Command+C.

Paste the information into a text file.

The following is an example of text copied from the GPU
Commands pane:

Can you find the errant draw call in the call hierarchy?

Figure 11. Examining the call thumbnails.

Select the frame you're investigating. In the
GPU Commands pane, scan the thumbnail images
to the left of each draw call. Hover your cursor
over a thumbnail to see a larger image. The thumbnails show the result of each
draw call and help you find the draw call where an unexpected result appears.

Is the rendering overdrawn by a later call?

If you see that the draw call renders properly in the middle of the frame, but
it's hidden by the end of the frame, then it's likely that the draw call becomes
obscured or is cleared. Scan forward through the frame to see if you can identify
the location where this happens.

Can you see the problem in the framebuffer?

After you find a troublesome draw call, select it in the GPU
Debugger pane and then select the Framebuffer tab. The
framebuffer content appears in the Framebuffer pane.

Figure 12. Looking at the framebuffer of the draw call.

Figure 13. Examining the geometry rendering.

A draw call can affect the color, depth, and stencil buffers. Depending on the
current state, the draw call can write to some or all of these buffers. Check
the color buffer and depth buffers to see if you can find your draw call being
rendered:

Click Color Buffer. Can you see the draw call in the color buffer?

Click Depth Buffer. Can you see the silhouette of the draw
call in the depth buffer?

Select the Geometry tab. In the Geometry pane,
see if you recognize the geometry. If you can find the geometry but can't see it
in the framebuffer, it could mean that the draw call is offscreen or the
vertex shader is broken, for example.

If you still can't find the issue, maybe the draw call is executed with zero
alpha. In the Framebuffer pane, click Color
Channels and then deselect Alpha to see if the alpha
channel is the issue.

Figure 14. Turning off the alpha channel.

Figure 15. Investigating the state variables.

Are the state variables correct?

With the draw call selected in the GPU Commands pane, click the
GPU State tab. In the GPU State pane,
check the following OpenGL ES state variables, which
can dramatically affect rendering:

Does the mesh render as you'd expect?

A bad mesh can have a variety of symptoms, such as stray triangles, incorrect
lighting due to poor surface normals, or a "polygon soup," an unordered
collection of triangles. You can use the Geometry pane to check
the polygon mesh of the draw call before it's transformed by the vertex shader.

Select the draw call in the GPU Commands pane, select the
Geometry tab, and then do the following in the Geometry pane:

Click Wireframe. Does the connectivity of the mesh look correct?

Click the shading buttons. Do the mesh normals look correct?

Zoom in on and rotate the mesh to examine it. Does the mesh appear as authored?

Figure 17. Examining textures.

Do the textures render as you'd expect?

If the mesh looks as expected but the draw call does not appear to be correct,
then there may be an issue with one of the source textures. Select the draw call
in the GPU Commands pane, select the Textures
tab, and then select the texture from the menu. In the Textures pane,
use the buttons to investigate the texture.

Does the blend state make sense?

With the draw call selected in the GPU Commands pane, click the
GPU State tab. Check the following OpenGL ES state variable:
Contexts > n >
Enabled.

If it's true, then alpha blending is enabled. This is controlled by a
GL_BLEND value for the glEnable()
and glDisable()
functions.

To compose the output of the fragment shader into the framebuffer, alpha
blending also uses other values in Contexts >
n > FragmentOperations >
Blend.

For more information about how blending works, see the glBlendFunc()
function.

Does the depth state make sense?

If it's true, then depth testing is enabled. This is controlled by a
GL_DEPTH_TEST value for the glEnable()
and glDisable()
functions.

Depth testing determines whether to draw a fragment based on the fragment depth
and the existing depth value in the framebuffer. For more information about how
depth testing works, see the glDepthFunc()
function.